summaryrefslogtreecommitdiff
path: root/Core
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-22 17:11:19 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:14:50 +0800
commit2cc68ed95f4e6a5b6256a6cc1e9f6a585a7d2ba7 (patch)
treee6f0cc497ee0f06782388ab114fd2f3d37bddcc5 /Core
parenta6747ab91782ba4309b5f12301c8b43b1b4702dd (diff)
downloadedk2-platforms-2cc68ed95f4e6a5b6256a6cc1e9f6a585a7d2ba7.tar.xz
UefiCpuPkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Core')
-rw-r--r--Core/UefiCpuPkg/Application/Cpuid/Cpuid.c1466
-rw-r--r--Core/UefiCpuPkg/Application/Cpuid/Cpuid.inf48
-rw-r--r--Core/UefiCpuPkg/Application/Cpuid/Cpuid.uni22
-rw-r--r--Core/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni22
-rw-r--r--Core/UefiCpuPkg/Contributions.txt218
-rw-r--r--Core/UefiCpuPkg/CpuDxe/ApStartup.c478
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuDxe.c931
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuDxe.h256
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuDxe.inf95
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuDxe.uni22
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni20
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuGdt.c161
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuGdt.h74
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuMp.c1806
-rw-r--r--Core/UefiCpuPkg/CpuDxe/CpuMp.h660
-rw-r--r--Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S57
-rw-r--r--Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm58
-rw-r--r--Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm76
-rw-r--r--Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm68
-rw-r--r--Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.S60
-rw-r--r--Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm54
-rw-r--r--Core/UefiCpuPkg/CpuDxe/X64/MpAsm.asm76
-rw-r--r--Core/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm70
-rw-r--r--Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c536
-rw-r--r--Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h225
-rw-r--r--Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf51
-rw-r--r--Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni22
-rw-r--r--Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni20
-rw-r--r--Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c413
-rw-r--r--Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h162
-rw-r--r--Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf52
-rw-r--r--Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni21
-rw-r--r--Core/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni19
-rw-r--r--Core/UefiCpuPkg/CpuIoPei/CpuIoPei.c864
-rw-r--r--Core/UefiCpuPkg/CpuIoPei/CpuIoPei.h448
-rw-r--r--Core/UefiCpuPkg/CpuIoPei/CpuIoPei.inf51
-rw-r--r--Core/UefiCpuPkg/CpuIoPei/CpuIoPei.uni22
-rw-r--r--Core/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni20
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuBist.c263
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuMpPei.c884
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuMpPei.h315
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuMpPei.inf96
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuMpPei.uni22
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni20
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc39
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm250
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm229
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/Microcode.c213
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/Microcode.h58
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/PeiMpServices.c956
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/PeiMpServices.h377
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc41
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm290
-rw-r--r--Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm281
-rw-r--r--Core/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c271
-rw-r--r--Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf68
-rw-r--r--Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni40
-rw-r--r--Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni20
-rw-r--r--Core/UefiCpuPkg/Include/AcpiCpuData.h160
-rw-r--r--Core/UefiCpuPkg/Include/CpuHotPlugData.h33
-rw-r--r--Core/UefiCpuPkg/Include/Library/LocalApicLib.h415
-rw-r--r--Core/UefiCpuPkg/Include/Library/MtrrLib.h386
-rw-r--r--Core/UefiCpuPkg/Include/Library/PlatformSecLib.h70
-rw-r--r--Core/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h401
-rw-r--r--Core/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h109
-rw-r--r--Core/UefiCpuPkg/Include/Library/UefiCpuLib.h38
-rw-r--r--Core/UefiCpuPkg/Include/Protocol/SmmCpuService.h209
-rw-r--r--Core/UefiCpuPkg/Include/Register/ArchitecturalMsr.h5801
-rw-r--r--Core/UefiCpuPkg/Include/Register/Cpuid.h3406
-rw-r--r--Core/UefiCpuPkg/Include/Register/LocalApic.h207
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr.h48
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/AtomMsr.h878
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h265
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/Core2Msr.h1325
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/CoreMsr.h1074
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h5995
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h2575
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h2830
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h7196
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/P6Msr.h1608
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h2550
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h643
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h121
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h4703
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h1468
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h1008
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h182
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h1430
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h254
-rw-r--r--Core/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h1426
-rw-r--r--Core/UefiCpuPkg/Include/Register/SmramSaveStateMap.h190
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf46
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S73
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm79
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S57
-rw-r--r--Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm62
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c942
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf49
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni23
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c1037
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf49
-rw-r--r--Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni23
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c219
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h284
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf61
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c204
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c204
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h44
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S667
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm467
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c184
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf61
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c294
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c183
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf57
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf61
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c133
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c235
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h46
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S433
-rw-r--r--Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm389
-rw-r--r--Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.c2147
-rw-r--r--Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf46
-rw-r--r--Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni22
-rw-r--r--Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c90
-rw-r--r--Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf37
-rw-r--r--Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni20
-rw-r--r--Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c216
-rw-r--r--Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf67
-rw-r--r--Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni31
-rw-r--r--Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c266
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c658
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf39
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni18
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c108
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf40
-rw-r--r--Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni18
-rw-r--r--Core/UefiCpuPkg/License.txt25
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c425
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf70
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni21
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni18
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h30
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c269
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf82
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni23
-rw-r--r--Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni18
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c512
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c486
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h181
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S165
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm168
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c130
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c48
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S169
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm177
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S911
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm738
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c96
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S84
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm94
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c80
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h97
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c1410
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c1517
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h797
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf161
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni21
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni18
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c1434
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h138
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h172
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c700
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c116
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S204
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm206
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c691
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c67
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S196
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm196
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S610
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm413
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c70
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S141
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm132
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c316
-rw-r--r--Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h105
-rw-r--r--Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni21
-rw-r--r--Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni17
-rw-r--r--Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf38
-rw-r--r--Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb60
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.rawbin0 -> 516 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.rawbin0 -> 484 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.rawbin0 -> 884 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf36
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni21
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.rawbin0 -> 28676 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.rawbin0 -> 28676 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.rawbin0 -> 28676 bytes
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni17
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Build.py53
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc31
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm26
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm48
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm133
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm71
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm45
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm30
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm86
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm200
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Main.asm106
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm28
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc25
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt41
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni21
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni17
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm132
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py26
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf36
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb70
-rw-r--r--Core/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm78
-rw-r--r--Core/UefiCpuPkg/SecCore/FindPeiCore.c198
-rw-r--r--Core/UefiCpuPkg/SecCore/Ia32/ResetVec.asm16106
-rw-r--r--Core/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb103
-rw-r--r--Core/UefiCpuPkg/SecCore/SecCore.inf72
-rw-r--r--Core/UefiCpuPkg/SecCore/SecCore.uni24
-rw-r--r--Core/UefiCpuPkg/SecCore/SecCoreExtra.uni18
-rw-r--r--Core/UefiCpuPkg/SecCore/SecMain.c295
-rw-r--r--Core/UefiCpuPkg/SecCore/SecMain.h109
-rw-r--r--Core/UefiCpuPkg/UefiCpuPkg.dec210
-rw-r--r--Core/UefiCpuPkg/UefiCpuPkg.dsc126
-rw-r--r--Core/UefiCpuPkg/UefiCpuPkg.uni149
-rw-r--r--Core/UefiCpuPkg/UefiCpuPkgExtra.uni20
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.S38
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.asm45
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c1160
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf97
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni26
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni20
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.S37
-rw-r--r--Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.asm41
246 files changed, 93415 insertions, 0 deletions
diff --git a/Core/UefiCpuPkg/Application/Cpuid/Cpuid.c b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.c
new file mode 100644
index 0000000000..8726a85f4e
--- /dev/null
+++ b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.c
@@ -0,0 +1,1466 @@
+/** @file
+ UEFI Application to display CPUID leaf information.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Register/Cpuid.h>
+
+///
+/// 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: 1 GByte pages, 4-way set associative, 4 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." },
+ { 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" }
+};
+
+///
+/// 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 (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;
+ 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, NULL
+ );
+ if (Ebx.Uint32 != 0 || Ecx.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, 0);
+ 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, PQM);
+ PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs);
+ PRINT_BIT_FIELD (Ebx, MPX);
+ PRINT_BIT_FIELD (Ebx, PQE);
+ PRINT_BIT_FIELD (Ebx, RDSEED);
+ PRINT_BIT_FIELD (Ebx, ADX);
+ PRINT_BIT_FIELD (Ebx, SMAP);
+ PRINT_BIT_FIELD (Ebx, CLFLUSHOPT);
+ PRINT_BIT_FIELD (Ebx, IntelProcessorTrace);
+ PRINT_BIT_FIELD (Ecx, PREFETCHWT1);
+ PRINT_BIT_FIELD (Ecx, PKU);
+ PRINT_BIT_FIELD (Ecx, OSPKE);
+ }
+ SubLeaf++;
+ } while (SubLeaf <= Eax);
+}
+
+/**
+ 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);
+}
+
+/**
+ Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels.
+
+**/
+VOID
+CpuidExtendedTopology (
+ VOID
+ )
+{
+ CPUID_EXTENDED_TOPOLOGY_EAX Eax;
+ CPUID_EXTENDED_TOPOLOGY_EBX Ebx;
+ CPUID_EXTENDED_TOPOLOGY_ECX Ecx;
+ UINT32 Edx;
+ UINT32 LevelNumber;
+
+ if (CPUID_EXTENDED_TOPOLOGY > gMaximumBasicFunction) {
+ return;
+ }
+
+ LevelNumber = 0;
+ do {
+ AsmCpuidEx (
+ CPUID_EXTENDED_TOPOLOGY, LevelNumber,
+ &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx
+ );
+ if (Eax.Bits.ApicIdShift != 0) {
+ Print (L"CPUID_EXTENDED_TOPOLOGY (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_TOPOLOGY, 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);
+ }
+ LevelNumber++;
+ } while (Eax.Bits.ApicIdShift != 0);
+}
+
+/**
+ 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, 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_VALUE (Ebx, EnabledSaveStateSize);
+ PRINT_VALUE (Ecx, SupportedSaveStateSize);
+ PRINT_VALUE (Edx, XCR0_Supported_32_63);
+
+ CpuidExtendedStateSubLeaf ();
+ CpuidExtendedStateSizeOffset ();
+}
+
+/**
+ Display CPUID_PLATFORM_QOS_MONITORING enumeration sub-leaf.
+
+**/
+VOID
+CpuidPlatformQosMonitoringEnumerationSubLeaf (
+ VOID
+ )
+{
+ UINT32 Ebx;
+ CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx;
+
+ if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) {
+ return;
+ }
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF,
+ NULL, &Ebx, NULL, &Edx.Uint32
+ );
+ Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_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, L3CacheQosEnforcement);
+}
+
+/**
+ Display CPUID_PLATFORM_QOS_MONITORING capability sub-leaf.
+
+**/
+VOID
+CpuidPlatformQosMonitoringCapabilitySubLeaf (
+ VOID
+ )
+{
+ UINT32 Ebx;
+ UINT32 Ecx;
+ CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX Edx;
+
+ if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) {
+ return;
+ }
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF,
+ NULL, &Ebx, &Ecx, &Edx.Uint32
+ );
+ Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_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);
+}
+
+/**
+ Display CPUID_PLATFORM_QOS_ENFORCEMENT sub-leaf.
+
+**/
+VOID
+CpuidPlatformQosEnforcementResidSubLeaf (
+ VOID
+ )
+{
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX Eax;
+ UINT32 Ebx;
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX Ecx;
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EDX Edx;
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF,
+ &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32
+ );
+ Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_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, CosUpdatesInfrequent);
+ PRINT_BIT_FIELD (Ecx, CodeDataPrioritization);
+ PRINT_BIT_FIELD (Edx, HighestCosNumber);
+}
+
+/**
+ Display CPUID_PLATFORM_QOS_ENFORCEMENT main leaf and sub-leaf.
+
+**/
+VOID
+CpuidPlatformQosEnforcementMainLeaf (
+ VOID
+ )
+{
+ CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX Ebx;
+
+ if (CPUID_PLATFORM_QOS_ENFORCEMENT > gMaximumBasicFunction) {
+ return;
+ }
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF,
+ NULL, &Ebx.Uint32, NULL, NULL
+ );
+ Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF);
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0);
+ PRINT_BIT_FIELD (Ebx, L3CacheQosEnforcement);
+
+ CpuidPlatformQosEnforcementResidSubLeaf ();
+}
+
+/**
+ 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 (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 (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;
+
+ if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) {
+ return;
+ }
+
+ AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, NULL, 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, 0, 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_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 ();
+ CpuidExtendedStateMainLeaf ();
+ CpuidPlatformQosMonitoringEnumerationSubLeaf ();
+ CpuidPlatformQosMonitoringCapabilitySubLeaf ();
+ CpuidPlatformQosEnforcementMainLeaf ();
+ CpuidEnumerationOfIntelSgx ();
+ CpuidIntelProcessorTraceMainLeaf ();
+ CpuidTimeStampCounter ();
+ CpuidProcessorFrequency ();
+ CpuidSocVendor ();
+ CpuidExtendedFunction ();
+ CpuidExtendedCpuSig ();
+ CpuidProcessorBrandString ();
+ CpuidExtendedCacheInfo ();
+ CpuidExtendedTimeStampCounter ();
+ CpuidVirPhyAddressSize ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/UefiCpuPkg/Application/Cpuid/Cpuid.inf b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.inf
new file mode 100644
index 0000000000..0d71b115d9
--- /dev/null
+++ b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.inf
@@ -0,0 +1,48 @@
+## @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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# 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 = 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/Core/UefiCpuPkg/Application/Cpuid/Cpuid.uni b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.uni
new file mode 100644
index 0000000000..32dee43414
--- /dev/null
+++ b/Core/UefiCpuPkg/Application/Cpuid/Cpuid.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni b/Core/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni
new file mode 100644
index 0000000000..b4251e23cc
--- /dev/null
+++ b/Core/UefiCpuPkg/Application/Cpuid/CpuidExtra.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPUID Application"
diff --git a/Core/UefiCpuPkg/Contributions.txt b/Core/UefiCpuPkg/Contributions.txt
new file mode 100644
index 0000000000..f87cbd73c6
--- /dev/null
+++ b/Core/UefiCpuPkg/Contributions.txt
@@ -0,0 +1,218 @@
+
+======================
+= Code Contributions =
+======================
+
+To make a contribution to a TianoCore project, follow these steps.
+1. Create a change description in the format specified below to
+ use in the source control commit log.
+2. Your commit message must include your "Signed-off-by" signature,
+ and "Contributed-under" message.
+3. Your "Contributed-under" message explicitly states that the
+ contribution is made under the terms of the specified
+ contribution agreement. Your "Contributed-under" message
+ must include the name of contribution agreement and version.
+ For example: Contributed-under: TianoCore Contribution Agreement 1.0
+ The "TianoCore Contribution Agreement" is included below in
+ this document.
+4. Submit your code to the TianoCore project using the process
+ that the project documents on its web page. If the process is
+ not documented, then submit the code on development email list
+ for the project.
+5. It is preferred that contributions are submitted using the same
+ copyright license as the base project. When that is not possible,
+ then contributions using the following licenses can be accepted:
+ * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause
+ * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause
+ * MIT: http://opensource.org/licenses/MIT
+ * Python-2.0: http://opensource.org/licenses/Python-2.0
+ * Zlib: http://opensource.org/licenses/Zlib
+
+ Contributions of code put into the public domain can also be
+ accepted.
+
+ Contributions using other licenses might be accepted, but further
+ review will be required.
+
+=====================================================
+= Change Description / Commit Message / Patch Email =
+=====================================================
+
+Your change description should use the standard format for a
+commit message, and must include your "Signed-off-by" signature
+and the "Contributed-under" message.
+
+== Sample Change Description / Commit Message =
+
+=== Start of sample patch email message ===
+
+From: Contributor Name <contributor@example.com>
+Subject: [PATCH] CodeModule: Brief-single-line-summary
+
+Full-commit-message
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Contributor Name <contributor@example.com>
+---
+
+An extra message for the patch email which will not be considered part
+of the commit message can be added here.
+
+Patch content inline or attached
+
+=== End of sample patch email message ===
+
+=== Notes for sample patch email ===
+
+* The first line of commit message is taken from the email's subject
+ line following [PATCH]. The remaining portion of the commit message
+ is the email's content until the '---' line.
+* git format-patch is one way to create this format
+
+=== Definitions for sample patch email ===
+
+* "CodeModule" is a short idenfier for the affected code. For
+ example MdePkg, or MdeModulePkg UsbBusDxe.
+* "Brief-single-line-summary" is a short summary of the change.
+* The entire first line should be less than ~70 characters.
+* "Full-commit-message" a verbose multiple line comment describing
+ the change. Each line should be less than ~70 characters.
+* "Contributed-under" explicitely states that the contribution is
+ made under the terms of the contribtion agreement. This
+ agreement is included below in this document.
+* "Signed-off-by" is the contributor's signature identifying them
+ by their real/legal name and their email address.
+
+========================================
+= TianoCore Contribution Agreement 1.0 =
+========================================
+
+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE
+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE
+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR
+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE
+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED
+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS
+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
+USE THE CONTENT.
+
+Unless otherwise indicated, all Content made available on the TianoCore
+site is provided to you under the terms and conditions of the BSD
+License ("BSD"). A copy of the BSD License is available at
+http://opensource.org/licenses/bsd-license.php
+or when applicable, in the associated License.txt file.
+
+Certain other content may be made available under other licenses as
+indicated in or with such Content. (For example, in a License.txt file.)
+
+You accept and agree to the following terms and conditions for Your
+present and future Contributions submitted to TianoCore site. Except
+for the license granted to Intel hereunder, You reserve all right,
+title, and interest in and to Your Contributions.
+
+== SECTION 1: Definitions ==
+* "You" or "Contributor" shall mean the copyright owner or legal
+ entity authorized by the copyright owner that is making a
+ Contribution hereunder. All other entities that control, are
+ controlled by, or are under common control with that entity are
+ considered to be a single Contributor. For the purposes of this
+ definition, "control" means (i) the power, direct or indirect, to
+ cause the direction or management of such entity, whether by
+ contract or otherwise, or (ii) ownership of fifty percent (50%)
+ or more of the outstanding shares, or (iii) beneficial ownership
+ of such entity.
+* "Contribution" shall mean any original work of authorship,
+ including any modifications or additions to an existing work,
+ that is intentionally submitted by You to the TinaoCore site for
+ inclusion in, or documentation of, any of the Content. For the
+ purposes of this definition, "submitted" means any form of
+ electronic, verbal, or written communication sent to the
+ TianoCore site or its representatives, including but not limited
+ to communication on electronic mailing lists, source code
+ control systems, and issue tracking systems that are managed by,
+ or on behalf of, the TianoCore site for the purpose of
+ discussing and improving the Content, but excluding
+ communication that is conspicuously marked or otherwise
+ designated in writing by You as "Not a Contribution."
+
+== SECTION 2: License for Contributions ==
+* Contributor hereby agrees that redistribution and use of the
+ Contribution 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 Contributor's
+ copyright notice, this list of conditions and the following
+ disclaimer.
+** Redistributions in binary form must reproduce the Contributor's
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+* Disclaimer. None of the names of Contributor, Intel, or the names
+ of their respective contributors may be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+* Contributor grants a license (with the right to sublicense) under
+ claims of Contributor's patents that Contributor can license that
+ are infringed by the Contribution (as delivered by Contributor) to
+ make, use, distribute, sell, offer for sale, and import the
+ Contribution and derivative works thereof solely to the minimum
+ extent necessary for licensee to exercise the granted copyright
+ license; this patent license applies solely to those portions of
+ the Contribution that are unmodified. No hardware per se is
+ licensed.
+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE
+ CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "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
+ CONTRIBUTOR 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 THE
+ CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
+== SECTION 3: Representations ==
+* You represent that You are legally entitled to grant the above
+ license. If your employer(s) has rights to intellectual property
+ that You create that includes Your Contributions, You represent
+ that You have received permission to make Contributions on behalf
+ of that employer, that Your employer has waived such rights for
+ Your Contributions.
+* You represent that each of Your Contributions is Your original
+ creation (see Section 4 for submissions on behalf of others).
+ You represent that Your Contribution submissions include complete
+ details of any third-party license or other restriction
+ (including, but not limited to, related patents and trademarks)
+ of which You are personally aware and which are associated with
+ any part of Your Contributions.
+
+== SECTION 4: Third Party Contributions ==
+* Should You wish to submit work that is not Your original creation,
+ You may submit it to TianoCore site separately from any
+ Contribution, identifying the complete details of its source
+ and of any license or other restriction (including, but not
+ limited to, related patents, trademarks, and license agreements)
+ of which You are personally aware, and conspicuously marking the
+ work as "Submitted on behalf of a third-party: [named here]".
+
+== SECTION 5: Miscellaneous ==
+* Applicable Laws. Any claims arising under or relating to this
+ Agreement shall be governed by the internal substantive laws of
+ the State of Delaware or federal courts located in Delaware,
+ without regard to principles of conflict of laws.
+* Language. This Agreement is in the English language only, which
+ language shall be controlling in all respects, and all versions
+ of this Agreement in any other language shall be for accommodation
+ only and shall not be binding. All communications and notices made
+ or given pursuant to this Agreement, and all documentation and
+ support to be provided, unless otherwise noted, shall be in the
+ English language.
+
diff --git a/Core/UefiCpuPkg/CpuDxe/ApStartup.c b/Core/UefiCpuPkg/CpuDxe/ApStartup.c
new file mode 100644
index 0000000000..78fb26f985
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/ApStartup.c
@@ -0,0 +1,478 @@
+/** @file
+ CPU DXE AP Startup
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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"
+#include "CpuGdt.h"
+#include "CpuMp.h"
+
+#pragma pack(1)
+
+typedef struct {
+ UINT8 MoveIa32EferMsrToEcx[5];
+ UINT8 ReadIa32EferMsr[2];
+ UINT8 SetExecuteDisableBitEnableBit[4];
+ UINT8 WriteIa32EferMsr[2];
+
+#if defined (MDE_CPU_IA32)
+ UINT8 MovEaxCr3;
+ UINT32 Cr3Value;
+ UINT8 MovCr3Eax[3];
+
+ UINT8 MoveCr4ToEax[3];
+ UINT8 SetCr4Bit5[4];
+ UINT8 MoveEaxToCr4[3];
+
+ UINT8 MoveCr0ToEax[3];
+ UINT8 SetCr0PagingBit[4];
+ UINT8 MoveEaxToCr0[3];
+#endif
+} ENABLE_EXECUTE_DISABLE_CODE;
+
+ENABLE_EXECUTE_DISABLE_CODE mEnableExecuteDisableCodeTemplate = {
+ { 0xB9, 0x80, 0x00, 0x00, 0xC0 }, // mov ecx, 0xc0000080
+ { 0x0F, 0x32 }, // rdmsr
+ { 0x0F, 0xBA, 0xE8, 0x0B }, // bts eax, 11
+ { 0x0F, 0x30 }, // wrmsr
+
+#if defined (MDE_CPU_IA32)
+ 0xB8, 0x00000000, // mov eax, cr3 value
+ { 0x0F, 0x22, 0xd8 }, // mov cr3, eax
+
+ { 0x0F, 0x20, 0xE0 }, // mov eax, cr4
+ { 0x0F, 0xBA, 0xE8, 0x05 }, // bts eax, 5
+ { 0x0F, 0x22, 0xE0 }, // mov cr4, eax
+
+ { 0x0F, 0x20, 0xC0 }, // mov eax, cr0
+ { 0x0F, 0xBA, 0xE8, 0x1F }, // bts eax, 31
+ { 0x0F, 0x22, 0xC0 }, // mov cr0, eax
+#endif
+};
+
+typedef struct {
+ UINT8 JmpToCli[2];
+
+ UINT16 GdtLimit;
+ UINT32 GdtBase;
+
+ UINT8 Cli;
+
+ UINT8 MovAxRealSegment; UINT16 RealSegment;
+ UINT8 MovDsAx[2];
+
+ UINT8 MovBxGdtr[3];
+ UINT8 LoadGdt[5];
+
+ UINT8 MovEaxCr0[2];
+ UINT32 MovEaxCr0Value;
+ UINT8 MovCr0Eax[3];
+
+ UINT8 FarJmp32Flat[2]; UINT32 FlatJmpOffset; UINT16 FlatJmpSelector;
+
+ //
+ // Now in IA32
+ //
+ UINT8 MovEaxCr4;
+ UINT32 MovEaxCr4Value;
+ UINT8 MovCr4Eax[3];
+
+ UINT8 MoveDataSelectorIntoAx[2]; UINT16 FlatDataSelector;
+ UINT8 MoveFlatDataSelectorFromAxToDs[2];
+ UINT8 MoveFlatDataSelectorFromAxToEs[2];
+ UINT8 MoveFlatDataSelectorFromAxToFs[2];
+ UINT8 MoveFlatDataSelectorFromAxToGs[2];
+ UINT8 MoveFlatDataSelectorFromAxToSs[2];
+
+ //
+ // Code placeholder to enable PAE Execute Disable for IA32
+ // and enable Execute Disable Bit for X64
+ //
+ ENABLE_EXECUTE_DISABLE_CODE EnableExecuteDisable;
+
+#if defined (MDE_CPU_X64)
+ //
+ // Transition to X64
+ //
+ UINT8 MovEaxCr3;
+ UINT32 Cr3Value;
+ UINT8 MovCr3Eax[3];
+
+ UINT8 MoveCr4ToEax[3];
+ UINT8 SetCr4Bit5[4];
+ UINT8 MoveEaxToCr4[3];
+
+ UINT8 MoveLongModeEnableMsrToEcx[5];
+ UINT8 ReadLmeMsr[2];
+ UINT8 SetLongModeEnableBit[4];
+ UINT8 WriteLmeMsr[2];
+
+ UINT8 MoveCr0ToEax[3];
+ UINT8 SetCr0PagingBit[4];
+ UINT8 MoveEaxToCr0[3];
+ //UINT8 DeadLoop[2];
+
+ UINT8 FarJmp32LongMode; UINT32 LongJmpOffset; UINT16 LongJmpSelector;
+#endif // defined (MDE_CPU_X64)
+
+#if defined (MDE_CPU_X64)
+ UINT8 MovEaxOrRaxCpuDxeEntry[2]; UINTN CpuDxeEntryValue;
+#else
+ UINT8 MovEaxOrRaxCpuDxeEntry; UINTN CpuDxeEntryValue;
+#endif
+ UINT8 JmpToCpuDxeEntry[2];
+
+} STARTUP_CODE;
+
+#pragma pack()
+
+/**
+ This .asm code used for translating processor from 16 bit real mode into
+ 64 bit long mode. which help to create the mStartupCodeTemplate value.
+
+ To assemble:
+ * nasm -o ApStartup ApStartup.asm
+ Then disassemble:
+ * ndisasm -b 16 ApStartup
+ * ndisasm -b 16 -e 6 ApStartup
+ * ndisasm -b 32 -e 32 ApStartup (This -e offset may need adjustment)
+ * ndisasm -b 64 -e 0x83 ApStartup (This -e offset may need adjustment)
+
+ %define DEFAULT_CR0 0x00000023
+ %define DEFAULT_CR4 0x640
+
+ BITS 16
+
+ jmp short TransitionFromReal16To32BitFlat
+
+ ALIGN 2
+
+ Gdtr:
+ dw 0x5a5a
+ dd 0x5a5a5a5a
+
+ ;
+ ; Modified: EAX, EBX
+ ;
+ TransitionFromReal16To32BitFlat:
+
+ cli
+ mov ax, 0x5a5a
+ mov ds, ax
+
+ mov bx, Gdtr
+ o32 lgdt [ds:bx]
+
+ mov eax, cr4
+ btc eax, 5
+ mov cr4, eax
+
+ mov eax, DEFAULT_CR0
+ mov cr0, eax
+
+ jmp 0x5a5a:dword jumpTo32BitAndLandHere
+ BITS 32
+ jumpTo32BitAndLandHere:
+
+ mov eax, DEFAULT_CR4
+ mov cr4, eax
+
+ mov ax, 0x5a5a
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;
+ ; Jump to CpuDxe for IA32
+ ;
+ mov eax, 0x5a5a5a5a
+ or eax, eax
+ jz Transition32FlatTo64Flat
+ jmp eax
+
+ ;
+ ; Transition to X64
+ ;
+ Transition32FlatTo64Flat:
+ mov eax, 0x5a5a5a5a
+ mov cr3, eax
+
+ mov eax, cr4
+ bts eax, 5 ; enable PAE
+ mov cr4, eax
+
+ mov ecx, 0xc0000080
+ rdmsr
+ bts eax, 8 ; set LME
+ wrmsr
+
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax ; enable paging
+
+ ;
+ ; Jump to CpuDxe for X64
+ ;
+ jmp 0x5a5a:jumpTo64BitAndLandHere
+ BITS 64
+ jumpTo64BitAndLandHere:
+ mov rax, 0xcdcdcdcdcdcdcdcd
+ jmp rax
+**/
+STARTUP_CODE mStartupCodeTemplate = {
+ { 0xeb, 0x06 }, // Jump to cli
+ 0, // GDT Limit
+ 0, // GDT Base
+ 0xfa, // cli (Clear Interrupts)
+ 0xb8, 0x0000, // mov ax, RealSegment
+ { 0x8e, 0xd8 }, // mov ds, ax
+ { 0xBB, 0x02, 0x00 }, // mov bx, Gdtr
+ { 0x3e, 0x66, 0x0f, 0x01, 0x17 }, // lgdt [ds:bx]
+ { 0x66, 0xB8 }, 0x00000023, // mov eax, cr0 value
+ { 0x0F, 0x22, 0xC0 }, // mov cr0, eax
+ { 0x66, 0xEA }, // far jmp to 32-bit flat
+ OFFSET_OF(STARTUP_CODE, MovEaxCr4),
+ LINEAR_CODE_SEL,
+ 0xB8, 0x00000640, // mov eax, cr4 value
+ { 0x0F, 0x22, 0xe0 }, // mov cr4, eax
+ { 0x66, 0xb8 }, CPU_DATA_SEL, // mov ax, FlatDataSelector
+ { 0x8e, 0xd8 }, // mov ds, ax
+ { 0x8e, 0xc0 }, // mov es, ax
+ { 0x8e, 0xe0 }, // mov fs, ax
+ { 0x8e, 0xe8 }, // mov gs, ax
+ { 0x8e, 0xd0 }, // mov ss, ax
+
+#if defined (MDE_CPU_X64)
+ //
+ // Code placeholder to enable Execute Disable Bit for X64
+ // Default is all NOP - No Operation
+ //
+ {
+ { 0x90, 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90 },
+ { 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90 },
+ },
+
+ 0xB8, 0x00000000, // mov eax, cr3 value
+ { 0x0F, 0x22, 0xd8 }, // mov cr3, eax
+
+ { 0x0F, 0x20, 0xE0 }, // mov eax, cr4
+ { 0x0F, 0xBA, 0xE8, 0x05 }, // bts eax, 5
+ { 0x0F, 0x22, 0xE0 }, // mov cr4, eax
+
+ { 0xB9, 0x80, 0x00, 0x00, 0xC0 }, // mov ecx, 0xc0000080
+ { 0x0F, 0x32 }, // rdmsr
+ { 0x0F, 0xBA, 0xE8, 0x08 }, // bts eax, 8
+ { 0x0F, 0x30 }, // wrmsr
+
+ { 0x0F, 0x20, 0xC0 }, // mov eax, cr0
+ { 0x0F, 0xBA, 0xE8, 0x1F }, // bts eax, 31
+ { 0x0F, 0x22, 0xC0 }, // mov cr0, eax
+
+ 0xEA, // FarJmp32LongMode
+ OFFSET_OF(STARTUP_CODE, MovEaxOrRaxCpuDxeEntry),
+ LINEAR_CODE64_SEL,
+#else
+ //
+ // Code placeholder to enable PAE Execute Disable for IA32
+ // Default is all NOP - No Operation
+ //
+ {
+ { 0x90, 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90 },
+ { 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90 },
+
+ 0x90, 0x90909090,
+ { 0x90, 0x90, 0x90 },
+
+ { 0x90, 0x90, 0x90 },
+ { 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90, 0x90 },
+
+ { 0x90, 0x90, 0x90 },
+ { 0x90, 0x90, 0x90, 0x90 },
+ { 0x90, 0x90, 0x90 },
+ },
+#endif
+
+ //0xeb, 0xfe, // jmp $
+#if defined (MDE_CPU_X64)
+ { 0x48, 0xb8 }, 0x0, // mov rax, X64 CpuDxe MP Entry Point
+#else
+ 0xB8, 0x0, // mov eax, IA32 CpuDxe MP Entry Point
+#endif
+ { 0xff, 0xe0 }, // jmp to eax/rax (CpuDxe MP Entry Point)
+
+};
+
+volatile STARTUP_CODE *StartupCode = NULL;
+
+/**
+ 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.
+
+ @retval TRUE BSP Execute Disable is enabled.
+ @retval FALSE BSP Execute Disable is not enabled.
+
+**/
+BOOLEAN
+IsBspExecuteDisableEnabled (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT64 MsrRegisters;
+ BOOLEAN Enabled;
+
+ Enabled = FALSE;
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ //
+ // Cpuid 0x80000001
+ // Bit 20: Execute Disable Bit available.
+ //
+ if ((RegEdx & BIT20) != 0) {
+ MsrRegisters = AsmReadMsr64 (0xC0000080);
+ //
+ // Msr 0xC0000080
+ // Bit 11: Execute Disable Bit enable.
+ //
+ if ((MsrRegisters & BIT11) != 0) {
+ Enabled = TRUE;
+ }
+ }
+ }
+
+ return Enabled;
+}
+
+/**
+ Prepares Startup Code for APs.
+ This function prepares Startup Code for APs.
+
+ @retval EFI_SUCCESS The APs were started
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate memory to start APs
+
+**/
+EFI_STATUS
+PrepareAPStartupCode (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ IA32_DESCRIPTOR Gdtr;
+ EFI_PHYSICAL_ADDRESS StartAddress;
+
+ StartAddress = BASE_1MB;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (sizeof (*StartupCode)),
+ &StartAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ StartupCode = (STARTUP_CODE*)(VOID*)(UINTN) StartAddress;
+ CopyMem ((VOID*) StartupCode, &mStartupCodeTemplate, sizeof (*StartupCode));
+ StartupCode->RealSegment = (UINT16) (((UINTN) StartAddress) >> 4);
+
+ AsmReadGdtr (&Gdtr);
+ StartupCode->GdtLimit = Gdtr.Limit;
+ StartupCode->GdtBase = (UINT32) Gdtr.Base;
+
+ StartupCode->CpuDxeEntryValue = (UINTN) AsmApEntryPoint;
+
+ StartupCode->FlatJmpOffset += (UINT32) StartAddress;
+
+ if (IsBspExecuteDisableEnabled ()) {
+ CopyMem (
+ (VOID*) &StartupCode->EnableExecuteDisable,
+ &mEnableExecuteDisableCodeTemplate,
+ sizeof (ENABLE_EXECUTE_DISABLE_CODE)
+ );
+ }
+#if defined (MDE_CPU_X64)
+ StartupCode->Cr3Value = (UINT32) AsmReadCr3 ();
+ StartupCode->LongJmpOffset += (UINT32) StartAddress;
+#else
+ StartupCode->EnableExecuteDisable.Cr3Value = (UINT32) AsmReadCr3 ();
+#endif
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Free the code buffer of startup AP.
+
+**/
+VOID
+FreeApStartupCode (
+ VOID
+ )
+{
+ if (StartupCode != NULL) {
+ gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)(VOID*) StartupCode,
+ EFI_SIZE_TO_PAGES (sizeof (*StartupCode)));
+ }
+}
+
+
+/**
+ Starts the Application Processors and directs them to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @retval EFI_SUCCESS The APs were started
+
+**/
+EFI_STATUS
+StartApsStackless (
+ VOID
+ )
+{
+ SendInitSipiSipiAllExcludingSelf ((UINT32)(UINTN)(VOID*) StartupCode);
+ //
+ // Wait for APs to arrive at the ApEntryPoint routine
+ //
+ MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Resets the Application Processor and directs it to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @param ProcessorId the AP of ProcessorId was reset
+**/
+VOID
+ResetApStackless (
+ IN UINT32 ProcessorId
+ )
+{
+ SendInitSipiSipi (ProcessorId,
+ (UINT32)(UINTN)(VOID*) StartupCode);
+}
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuDxe.c b/Core/UefiCpuPkg/CpuDxe/CpuDxe.c
new file mode 100644
index 0000000000..daf97bd4a6
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -0,0 +1,931 @@
+/** @file
+ CPU DXE Module.
+
+ Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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"
+#include "CpuMp.h"
+
+//
+// Global Variables
+//
+BOOLEAN InterruptState = FALSE;
+EFI_HANDLE mCpuHandle = NULL;
+BOOLEAN mIsFlushingGCD;
+UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
+UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
+
+FIXED_MTRR mFixedMtrrTable[] = {
+ {
+ MTRR_LIB_IA32_MTRR_FIX64K_00000,
+ 0,
+ 0x10000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX16K_80000,
+ 0x80000,
+ 0x4000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX16K_A0000,
+ 0xA0000,
+ 0x4000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_C0000,
+ 0xC0000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_C8000,
+ 0xC8000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_D0000,
+ 0xD0000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_D8000,
+ 0xD8000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_E0000,
+ 0xE0000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_E8000,
+ 0xE8000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_F0000,
+ 0xF0000,
+ 0x1000
+ },
+ {
+ MTRR_LIB_IA32_MTRR_FIX4K_F8000,
+ 0xF8000,
+ 0x1000
+ },
+};
+
+
+EFI_CPU_ARCH_PROTOCOL gCpu = {
+ CpuFlushCpuDataCache,
+ CpuEnableInterrupt,
+ CpuDisableInterrupt,
+ CpuGetInterruptState,
+ CpuInit,
+ CpuRegisterInterruptHandler,
+ CpuGetTimerValue,
+ CpuSetMemoryAttributes,
+ 1, // NumberOfTimers
+ 4 // DmaBufferAlignment
+};
+
+//
+// CPU Arch Protocol Functions
+//
+
+/**
+ Flush CPU data cache. If the instruction cache is fully coherent
+ with all DMA operations then function can just return EFI_SUCCESS.
+
+ @param This Protocol instance structure
+ @param Start Physical address to start flushing from.
+ @param Length Number of bytes to flush. Round up to chipset
+ granularity.
+ @param FlushType Specifies the type of flush operation to perform.
+
+ @retval EFI_SUCCESS If cache was flushed
+ @retval EFI_UNSUPPORTED If flush type is not supported.
+ @retval EFI_DEVICE_ERROR If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ )
+{
+ if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
+ AsmWbinvd ();
+ return EFI_SUCCESS;
+ } else if (FlushType == EfiCpuFlushTypeInvalidate) {
+ AsmInvd ();
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+
+/**
+ Enables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were enabled in the CPU
+ @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ EnableInterrupts ();
+
+ InterruptState = TRUE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Disables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ DisableInterrupts ();
+
+ InterruptState = FALSE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Return the state of interrupts.
+
+ @param This Protocol instance structure
+ @param State Pointer to the CPU's current interrupt state
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ )
+{
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *State = InterruptState;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Generates an INIT to the CPU.
+
+ @param This Protocol instance structure
+ @param InitType Type of CPU INIT to perform
+
+ @retval EFI_SUCCESS If CPU INIT occurred. This value should never be
+ seen.
+ @retval EFI_DEVICE_ERROR If CPU INIT failed.
+ @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Registers a function to be called from the CPU interrupt handler.
+
+ @param This Protocol instance structure
+ @param InterruptType Defines which interrupt to hook. IA-32
+ valid range is 0x00 through 0xFF
+ @param InterruptHandler A pointer to a function of type
+ EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. A null
+ pointer is an error condition.
+
+ @retval EFI_SUCCESS If handler 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
+CpuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
+}
+
+
+/**
+ Returns a timer value from one of the CPU's internal timers. There is no
+ inherent time interval between ticks but is a function of the CPU frequency.
+
+ @param This - Protocol instance structure.
+ @param TimerIndex - Specifies which CPU timer is requested.
+ @param TimerValue - Pointer to the returned timer value.
+ @param TimerPeriod - A pointer to the amount of time that passes
+ in femtoseconds (10-15) for each increment
+ of TimerValue. If TimerValue does not
+ increment at a predictable rate, then 0 is
+ returned. The amount of time that has
+ passed between two calls to GetTimerValue()
+ can be calculated with the formula
+ (TimerValue2 - TimerValue1) * TimerPeriod.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS - If the CPU timer count was returned.
+ @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
+ @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
+ @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ )
+{
+ if (TimerValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TimerIndex != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerValue = AsmReadTsc ();
+
+ if (TimerPeriod != NULL) {
+ //
+ // BugBug: Hard coded. Don't know how to do this generically
+ //
+ *TimerPeriod = 1000000000;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
+
+ This function modifies the attributes for the memory region specified by BaseAddress and
+ Length from their current attributes to the attributes specified by Attributes.
+
+ @param This The EFI_CPU_ARCH_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_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
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ RETURN_STATUS Status;
+ MTRR_MEMORY_CACHE_TYPE CacheType;
+ EFI_STATUS MpStatus;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+ MTRR_SETTINGS MtrrSettings;
+
+ if (!IsMtrrSupported ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // If this function is called because GCD SetMemorySpaceAttributes () is called
+ // by RefreshGcdMemoryAttributes (), then we are just synchronzing 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_INFO, " Flushing GCD\n"));
+ return EFI_SUCCESS;
+ }
+
+ switch (Attributes) {
+ 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;
+
+ case EFI_MEMORY_UCE:
+ case EFI_MEMORY_RP:
+ case EFI_MEMORY_XP:
+ case EFI_MEMORY_RUNTIME:
+ return EFI_UNSUPPORTED;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // call MTRR libary 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
+ TRUE, // SingleThread
+ NULL, // WaitEvent
+ 0, // TimeoutInMicrosecsond
+ &MtrrSettings, // ProcedureArgument
+ NULL // FailedCpuList
+ );
+ ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
+ }
+ }
+ return (EFI_STATUS) Status;
+}
+
+/**
+ Initializes the valid bits mask and valid address mask for MTRRs.
+
+ This function initializes the valid bits mask and valid address mask for MTRRs.
+
+**/
+VOID
+InitializeMtrrMask (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT8 PhysicalAddressBits;
+
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+
+ if (RegEax >= 0x80000008) {
+ 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;
+ }
+}
+
+/**
+ Gets GCD Mem Space type from MTRR Type.
+
+ This function gets GCD Mem Space type from MTRR Type.
+
+ @param MtrrAttributes MTRR memory type
+
+ @return GCD Mem Space type
+
+**/
+UINT64
+GetMemorySpaceAttributeFromMtrrType (
+ IN UINT8 MtrrAttributes
+ )
+{
+ switch (MtrrAttributes) {
+ case MTRR_CACHE_UNCACHEABLE:
+ return EFI_MEMORY_UC;
+ case MTRR_CACHE_WRITE_COMBINING:
+ return EFI_MEMORY_WC;
+ case MTRR_CACHE_WRITE_THROUGH:
+ return EFI_MEMORY_WT;
+ case MTRR_CACHE_WRITE_PROTECTED:
+ return EFI_MEMORY_WP;
+ case MTRR_CACHE_WRITE_BACK:
+ return EFI_MEMORY_WB;
+ default:
+ return 0;
+ }
+}
+
+/**
+ Searches memory descriptors covered by given memory range.
+
+ This function searches into the Gcd Memory Space for descriptors
+ (from StartIndex to EndIndex) that contains the memory range
+ specified by BaseAddress and Length.
+
+ @param MemorySpaceMap Gcd Memory Space Map as array.
+ @param NumberOfDescriptors Number of descriptors in map.
+ @param BaseAddress BaseAddress for the requested range.
+ @param Length Length for the requested range.
+ @param StartIndex Start index into the Gcd Memory Space Map.
+ @param EndIndex End index into the Gcd Memory Space Map.
+
+ @retval EFI_SUCCESS Search successfully.
+ @retval EFI_NOT_FOUND The requested descriptors does not exist.
+
+**/
+EFI_STATUS
+SearchGcdMemorySpaces (
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ OUT UINTN *StartIndex,
+ OUT UINTN *EndIndex
+ )
+{
+ UINTN Index;
+
+ *StartIndex = 0;
+ *EndIndex = 0;
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&
+ BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
+ *StartIndex = Index;
+ }
+ if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&
+ BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
+ *EndIndex = Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Sets the attributes for a specified range in Gcd Memory Space Map.
+
+ This function sets the attributes for a specified range in
+ Gcd Memory Space Map.
+
+ @param MemorySpaceMap Gcd Memory Space Map as array
+ @param NumberOfDescriptors Number of descriptors in map
+ @param BaseAddress BaseAddress for the range
+ @param Length Length for the range
+ @param Attributes Attributes to set
+
+ @retval EFI_SUCCESS Memory attributes set successfully
+ @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space
+
+**/
+EFI_STATUS
+SetGcdMemorySpaceAttributes (
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN StartIndex;
+ UINTN EndIndex;
+ EFI_PHYSICAL_ADDRESS RegionStart;
+ UINT64 RegionLength;
+
+ //
+ // Get all memory descriptors covered by the memory range
+ //
+ Status = SearchGcdMemorySpaces (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ BaseAddress,
+ Length,
+ &StartIndex,
+ &EndIndex
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Go through all related descriptors and set attributes accordingly
+ //
+ for (Index = StartIndex; Index <= EndIndex; Index++) {
+ if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
+ continue;
+ }
+ //
+ // Calculate the start and end address of the overlapping range
+ //
+ if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
+ RegionStart = BaseAddress;
+ } else {
+ RegionStart = MemorySpaceMap[Index].BaseAddress;
+ }
+ if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
+ RegionLength = BaseAddress + Length - RegionStart;
+ } else {
+ RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
+ }
+ //
+ // Set memory attributes according to MTRR attribute and the original attribute of descriptor
+ //
+ gDS->SetMemorySpaceAttributes (
+ RegionStart,
+ RegionLength,
+ (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Refreshes the GCD Memory Space attributes according to MTRRs.
+
+ This function refreshes the GCD Memory Space attributes according to MTRRs.
+
+**/
+VOID
+RefreshGcdMemoryAttributes (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN SubIndex;
+ UINT64 RegValue;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ UINT64 Attributes;
+ UINT64 CurrentAttributes;
+ UINT8 MtrrType;
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+ UINT64 DefaultAttributes;
+ VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+ MTRR_FIXED_SETTINGS MtrrFixedSettings;
+ UINT32 FirmwareVariableMtrrCount;
+ UINT8 DefaultMemoryType;
+
+ if (!IsMtrrSupported ()) {
+ return;
+ }
+
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();
+ ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+ mIsFlushingGCD = TRUE;
+ MemorySpaceMap = NULL;
+
+ //
+ // Initialize the valid bits mask and valid address mask for MTRRs
+ //
+ InitializeMtrrMask ();
+
+ //
+ // Get the memory attribute of variable MTRRs
+ //
+ MtrrGetMemoryAttributeInVariableMtrr (
+ mValidMtrrBitsMask,
+ mValidMtrrAddressMask,
+ VariableMtrr
+ );
+
+ //
+ // Get the memory space map from GCD
+ //
+ Status = gDS->GetMemorySpaceMap (
+ &NumberOfDescriptors,
+ &MemorySpaceMap
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DefaultMemoryType = (UINT8) MtrrGetDefaultMemoryType ();
+ DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (DefaultMemoryType);
+
+ //
+ // Set default attributes to all spaces.
+ //
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
+ continue;
+ }
+ gDS->SetMemorySpaceAttributes (
+ MemorySpaceMap[Index].BaseAddress,
+ MemorySpaceMap[Index].Length,
+ (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) |
+ (MemorySpaceMap[Index].Capabilities & DefaultAttributes)
+ );
+ }
+
+ //
+ // Go for variable MTRRs with WB attribute
+ //
+ for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
+ if (VariableMtrr[Index].Valid &&
+ VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK) {
+ SetGcdMemorySpaceAttributes (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ VariableMtrr[Index].BaseAddress,
+ VariableMtrr[Index].Length,
+ EFI_MEMORY_WB
+ );
+ }
+ }
+
+ //
+ // Go for variable MTRRs with the attribute except for WB and UC attributes
+ //
+ for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
+ if (VariableMtrr[Index].Valid &&
+ VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK &&
+ VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE) {
+ Attributes = GetMemorySpaceAttributeFromMtrrType ((UINT8) VariableMtrr[Index].Type);
+ SetGcdMemorySpaceAttributes (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ VariableMtrr[Index].BaseAddress,
+ VariableMtrr[Index].Length,
+ Attributes
+ );
+ }
+ }
+
+ //
+ // Go for variable MTRRs with UC attribute
+ //
+ for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
+ if (VariableMtrr[Index].Valid &&
+ VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE) {
+ SetGcdMemorySpaceAttributes (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ VariableMtrr[Index].BaseAddress,
+ VariableMtrr[Index].Length,
+ EFI_MEMORY_UC
+ );
+ }
+ }
+
+ //
+ // Go for fixed MTRRs
+ //
+ Attributes = 0;
+ BaseAddress = 0;
+ Length = 0;
+ MtrrGetFixedMtrr (&MtrrFixedSettings);
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ RegValue = MtrrFixedSettings.Mtrr[Index];
+ //
+ // Check for continuous fixed MTRR sections
+ //
+ for (SubIndex = 0; SubIndex < 8; SubIndex++) {
+ MtrrType = (UINT8) RShiftU64 (RegValue, SubIndex * 8);
+ CurrentAttributes = GetMemorySpaceAttributeFromMtrrType (MtrrType);
+ if (Length == 0) {
+ //
+ // A new MTRR attribute begins
+ //
+ Attributes = CurrentAttributes;
+ } else {
+ //
+ // If fixed MTRR attribute changed, then set memory attribute for previous atrribute
+ //
+ if (CurrentAttributes != Attributes) {
+ SetGcdMemorySpaceAttributes (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ BaseAddress,
+ Length,
+ Attributes
+ );
+ BaseAddress = mFixedMtrrTable[Index].BaseAddress + mFixedMtrrTable[Index].Length * SubIndex;
+ Length = 0;
+ Attributes = CurrentAttributes;
+ }
+ }
+ Length += mFixedMtrrTable[Index].Length;
+ }
+ }
+ //
+ // Handle the last fixed MTRR region
+ //
+ SetGcdMemorySpaceAttributes (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ BaseAddress,
+ Length,
+ Attributes
+ );
+
+ //
+ // Free memory space map allocated by GCD service GetMemorySpaceMap ()
+ //
+ if (MemorySpaceMap != NULL) {
+ FreePool (MemorySpaceMap);
+ }
+
+ mIsFlushingGCD = FALSE;
+}
+
+/**
+ Initialize Interrupt Descriptor Table for interrupt handling.
+
+**/
+VOID
+InitInterruptDescriptorTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+
+ VectorInfo = NULL;
+ Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList);
+ if (Status == EFI_SUCCESS && VectorInfoList != NULL) {
+ VectorInfo = VectorInfoList;
+ }
+ Status = InitializeCpuInterruptHandlers (VectorInfo);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Callback function for idle events.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+IdleLoopEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CpuSleep ();
+}
+
+
+/**
+ Initialize the state information for the CPU Architectural Protocol.
+
+ @param ImageHandle Image handle this driver.
+ @param SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Cannot create the thread
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT IdleLoopEvent;
+
+ InitializeFloatingPointUnits ();
+
+ //
+ // Make sure interrupts are disabled
+ //
+ DisableInterrupts ();
+
+ //
+ // Init GDT for DXE
+ //
+ InitGlobalDescriptorTable ();
+
+ //
+ // Setup IDT pointer, IDT and interrupt entry points
+ //
+ InitInterruptDescriptorTable ();
+
+ //
+ // Enable the local APIC for Virtual Wire Mode.
+ //
+ ProgramVirtualWireMode ();
+
+ //
+ // Install CPU Architectural Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuHandle,
+ &gEfiCpuArchProtocolGuid, &gCpu,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Refresh GCD memory space map according to MTRR value.
+ //
+ RefreshGcdMemoryAttributes ();
+
+ //
+ // Setup a callback for idle events
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IdleLoopEventCallback,
+ NULL,
+ &gIdleLoopEventGuid,
+ &IdleLoopEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ InitializeMpSupport ();
+
+ return Status;
+}
+
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuDxe.h b/Core/UefiCpuPkg/CpuDxe/CpuDxe.h
new file mode 100644
index 0000000000..2aef626cd5
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -0,0 +1,256 @@
+/** @file
+ CPU DXE Module.
+
+ Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_DXE_H_
+#define _CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/UefiLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/TimerLib.h>
+#include <Guid/IdleLoopEvent.h>
+#include <Guid/VectorHandoffTable.h>
+
+#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
+ EFI_MEMORY_WC | \
+ EFI_MEMORY_WT | \
+ EFI_MEMORY_WB | \
+ EFI_MEMORY_UCE \
+ )
+
+
+/**
+ Flush CPU data cache. If the instruction cache is fully coherent
+ with all DMA operations then function can just return EFI_SUCCESS.
+
+ @param This Protocol instance structure
+ @param Start Physical address to start flushing from.
+ @param Length Number of bytes to flush. Round up to chipset
+ granularity.
+ @param FlushType Specifies the type of flush operation to perform.
+
+ @retval EFI_SUCCESS If cache was flushed
+ @retval EFI_UNSUPPORTED If flush type is not supported.
+ @retval EFI_DEVICE_ERROR If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ );
+
+/**
+ Enables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were enabled in the CPU
+ @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+/**
+ Disables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+/**
+ Return the state of interrupts.
+
+ @param This Protocol instance structure
+ @param State Pointer to the CPU's current interrupt state
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ );
+
+/**
+ Generates an INIT to the CPU.
+
+ @param This Protocol instance structure
+ @param InitType Type of CPU INIT to perform
+
+ @retval EFI_SUCCESS If CPU INIT occurred. This value should never be
+ seen.
+ @retval EFI_DEVICE_ERROR If CPU INIT failed.
+ @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ );
+
+/**
+ Registers a function to be called from the CPU interrupt handler.
+
+ @param This Protocol instance structure
+ @param InterruptType Defines which interrupt to hook. IA-32
+ valid range is 0x00 through 0xFF
+ @param InterruptHandler A pointer to a function of type
+ EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. A null
+ pointer is an error condition.
+
+ @retval EFI_SUCCESS If handler 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
+CpuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+/**
+ Returns a timer value from one of the CPU's internal timers. There is no
+ inherent time interval between ticks but is a function of the CPU frequency.
+
+ @param This - Protocol instance structure.
+ @param TimerIndex - Specifies which CPU timer is requested.
+ @param TimerValue - Pointer to the returned timer value.
+ @param TimerPeriod - A pointer to the amount of time that passes
+ in femtoseconds (10-15) for each increment
+ of TimerValue. If TimerValue does not
+ increment at a predictable rate, then 0 is
+ returned. The amount of time that has
+ passed between two calls to GetTimerValue()
+ can be calculated with the formula
+ (TimerValue2 - TimerValue1) * TimerPeriod.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS - If the CPU timer count was returned.
+ @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
+ @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
+ @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ );
+
+/**
+ Set memory cacheability attributes for given range of memeory.
+
+ @param This Protocol instance structure
+ @param BaseAddress Specifies the start address of the
+ memory range
+ @param Length Specifies the length of the memory range
+ @param Attributes The memory cacheability for the memory range
+
+ @retval EFI_SUCCESS If the cacheability of that memory range is
+ set successfully
+ @retval EFI_UNSUPPORTED If the desired operation cannot be done
+ @retval EFI_INVALID_PARAMETER The input parameter is not correct,
+ such as Length = 0
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+/**
+ Initialize Global Descriptor Table.
+
+**/
+VOID
+InitGlobalDescriptorTable (
+ VOID
+ );
+
+/**
+ Sets the code selector (CS).
+
+ @param Selector Value of code selector.
+
+**/
+VOID
+EFIAPI
+SetCodeSelector (
+ UINT16 Selector
+ );
+
+/**
+ Sets the data selector (DS).
+
+ @param Selector Value of data selector.
+
+**/
+VOID
+EFIAPI
+SetDataSelectors (
+ UINT16 Selector
+ );
+
+#endif
+
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuDxe.inf b/Core/UefiCpuPkg/CpuDxe/CpuDxe.inf
new file mode 100644
index 0000000000..9db5303ae9
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -0,0 +1,95 @@
+## @file
+# Simple CPU driver installs CPU Architecture Protocol.
+#
+# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+ TimerLib
+ SynchronizationLib
+ HobLib
+ ReportStatusCodeLib
+
+[Sources]
+ ApStartup.c
+ CpuDxe.c
+ CpuDxe.h
+ CpuGdt.c
+ CpuGdt.h
+ CpuMp.c
+ CpuMp.h
+
+[Sources.IA32]
+ Ia32/CpuAsm.asm | MSFT
+ Ia32/CpuAsm.asm | INTEL
+ Ia32/CpuAsm.S | GCC
+ Ia32/MpAsm.asm | MSFT
+ Ia32/MpAsm.asm | INTEL
+ Ia32/MpAsm.nasm | GCC
+
+[Sources.X64]
+ X64/CpuAsm.asm | MSFT
+ X64/CpuAsm.asm | INTEL
+ X64/CpuAsm.S | GCC
+ X64/MpAsm.asm | MSFT
+ X64/MpAsm.asm | INTEL
+ X64/MpAsm.nasm | GCC
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## PRODUCES
+ gEfiMpServiceProtocolGuid ## SOMETIMES_PRODUCES
+
+[Guids]
+ gIdleLoopEventGuid ## CONSUMES ## Event
+ gEfiVectorHandoffTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+
+[Ppis]
+ gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB
+ gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuDxeExtra.uni
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuDxe.uni b/Core/UefiCpuPkg/CpuDxe/CpuDxe.uni
new file mode 100644
index 0000000000..5ac78100fb
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuDxe.uni
@@ -0,0 +1,22 @@
+// /** @file
+// Simple CPU driver installs CPU Architecture Protocol.
+//
+// Simple CPU driver installs CPU Architecture Protocol.
+//
+// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Installs CPU Architecture Protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Simple CPU driver installs CPU Architecture Protocol."
+
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni b/Core/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
new file mode 100644
index 0000000000..fbfc2e1fb2
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// CpuDxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPU Architectural DXE Driver"
+
+
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuGdt.c b/Core/UefiCpuPkg/CpuDxe/CpuGdt.c
new file mode 100644
index 0000000000..9ef2fdfefb
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuGdt.c
@@ -0,0 +1,161 @@
+/** @file
+ C based implemention of IA32 interrupt handling only
+ requiring a minimal assembly interrupt entry point.
+
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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"
+#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/Core/UefiCpuPkg/CpuDxe/CpuGdt.h b/Core/UefiCpuPkg/CpuDxe/CpuGdt.h
new file mode 100644
index 0000000000..2a00751602
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuGdt.h
@@ -0,0 +1,74 @@
+/** @file
+ C based implemention of IA32 interrupt handling only
+ requiring a minimal assembly interrupt entry point.
+
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_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/Core/UefiCpuPkg/CpuDxe/CpuMp.c b/Core/UefiCpuPkg/CpuDxe/CpuMp.c
new file mode 100644
index 0000000000..98fdfdf5e0
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -0,0 +1,1806 @@
+/** @file
+ CPU DXE Module.
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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"
+#include "CpuMp.h"
+
+UINTN gMaxLogicalProcessorNumber;
+UINTN gApStackSize;
+UINTN gPollInterval = 100; // 100 microseconds
+
+MP_SYSTEM_DATA mMpSystemData;
+EFI_HANDLE mMpServiceHandle = NULL;
+EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL;
+
+VOID *mCommonStack = 0;
+VOID *mTopOfApCommonStack = 0;
+VOID *mApStackStart = 0;
+
+volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;
+volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;
+
+EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
+ GetNumberOfProcessors,
+ GetProcessorInfo,
+ StartupAllAPs,
+ StartupThisAP,
+ SwitchBSP,
+ EnableDisableAP,
+ WhoAmI
+};
+
+/**
+ Get Mp Service Lock.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified processor
+
+**/
+VOID
+GetMpSpinLock (
+ IN CPU_DATA_BLOCK *CpuData
+ )
+{
+ while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+ CpuPause ();
+ }
+ CpuData->LockSelf = GetApicId ();
+}
+
+/**
+ Release Mp Service Lock.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified processor
+
+**/
+VOID
+ReleaseMpSpinLock (
+ IN CPU_DATA_BLOCK *CpuData
+ )
+{
+ ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+/**
+ Check whether caller processor is BSP.
+
+ @retval TRUE the caller is BSP
+ @retval FALSE the caller is AP
+
+**/
+BOOLEAN
+IsBSP (
+ VOID
+ )
+{
+ UINTN CpuIndex;
+ CPU_DATA_BLOCK *CpuData;
+
+ CpuData = NULL;
+
+ WhoAmI (&mMpServicesTemplate, &CpuIndex);
+ CpuData = &mMpSystemData.CpuDatas[CpuIndex];
+
+ return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE;
+}
+
+/**
+ Get the Application Processors state.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+
+ @retval CPU_STATE the AP status
+
+**/
+CPU_STATE
+GetApState (
+ IN CPU_DATA_BLOCK *CpuData
+ )
+{
+ CPU_STATE State;
+
+ GetMpSpinLock (CpuData);
+ State = CpuData->State;
+ ReleaseMpSpinLock (CpuData);
+
+ return State;
+}
+
+/**
+ Set the Application Processors state.
+
+ @param CpuData The pointer to CPU_DATA_BLOCK of specified AP
+ @param State The AP status
+
+**/
+VOID
+SetApState (
+ IN CPU_DATA_BLOCK *CpuData,
+ IN CPU_STATE State
+ )
+{
+ GetMpSpinLock (CpuData);
+ CpuData->State = State;
+ ReleaseMpSpinLock (CpuData);
+}
+
+/**
+ Set the Application Processor prepare to run a function specified
+ by Params.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+ @param Procedure A pointer to the function to be run on enabled APs of the system
+ @param ProcedureArgument Pointer to the optional parameter of the assigned function
+
+**/
+VOID
+SetApProcedure (
+ IN CPU_DATA_BLOCK *CpuData,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument
+ )
+{
+ GetMpSpinLock (CpuData);
+ CpuData->Parameter = ProcedureArgument;
+ CpuData->Procedure = Procedure;
+ ReleaseMpSpinLock (CpuData);
+}
+
+/**
+ Check the Application Processors Status whether contains the Flags.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+ @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
+
+ @retval TRUE the AP status includes the StatusFlag
+ @retval FALSE the AP status excludes the StatusFlag
+
+**/
+BOOLEAN
+TestCpuStatusFlag (
+ IN CPU_DATA_BLOCK *CpuData,
+ IN UINT32 Flags
+ )
+{
+ UINT32 Ret;
+
+ GetMpSpinLock (CpuData);
+ Ret = CpuData->Info.StatusFlag & Flags;
+ ReleaseMpSpinLock (CpuData);
+
+ return (BOOLEAN) (Ret != 0);
+}
+
+/**
+ Bitwise-Or of the Application Processors Status with the Flags.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+ @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
+
+**/
+VOID
+CpuStatusFlagOr (
+ IN CPU_DATA_BLOCK *CpuData,
+ IN UINT32 Flags
+ )
+{
+ GetMpSpinLock (CpuData);
+ CpuData->Info.StatusFlag |= Flags;
+ ReleaseMpSpinLock (CpuData);
+}
+
+/**
+ Bitwise-AndNot of the Application Processors Status with the Flags.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+ @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
+
+**/
+VOID
+CpuStatusFlagAndNot (
+ IN CPU_DATA_BLOCK *CpuData,
+ IN UINT32 Flags
+ )
+{
+ GetMpSpinLock (CpuData);
+ CpuData->Info.StatusFlag &= ~Flags;
+ ReleaseMpSpinLock (CpuData);
+}
+
+/**
+ Searches for the next blocking AP.
+
+ Search for the next AP that is put in blocking state by single-threaded StartupAllAPs().
+
+ @param NextNumber Pointer to the processor number of the next blocking AP.
+
+ @retval EFI_SUCCESS The next blocking AP has been found.
+ @retval EFI_NOT_FOUND No blocking AP exists.
+
+**/
+EFI_STATUS
+GetNextBlockedNumber (
+ OUT UINTN *NextNumber
+ )
+{
+ UINTN Number;
+ CPU_STATE CpuState;
+ CPU_DATA_BLOCK *CpuData;
+
+ for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
+ CpuData = &mMpSystemData.CpuDatas[Number];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState == CpuStateBlocked) {
+ *NextNumber = Number;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Check if the APs state are finished, and update them to idle state
+ by StartupAllAPs().
+
+**/
+VOID
+CheckAndUpdateAllAPsToIdleState (
+ VOID
+ )
+{
+ UINTN ProcessorNumber;
+ UINTN NextNumber;
+ CPU_DATA_BLOCK *CpuData;
+ EFI_STATUS Status;
+ CPU_STATE CpuState;
+
+ for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ //
+ // Skip Disabled processors
+ //
+ continue;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState == CpuStateFinished) {
+ mMpSystemData.FinishCount++;
+ if (mMpSystemData.SingleThread) {
+ Status = GetNextBlockedNumber (&NextNumber);
+ if (!EFI_ERROR (Status)) {
+ SetApState (&mMpSystemData.CpuDatas[NextNumber], CpuStateReady);
+ SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],
+ mMpSystemData.Procedure,
+ mMpSystemData.ProcedureArgument);
+ //
+ // If this AP previous state is blocked, we should
+ // wake up this AP by sent a SIPI. and avoid
+ // re-involve the sleeping state. we must call
+ // SetApProcedure() first.
+ //
+ ResetProcessorToIdleState (&mMpSystemData.CpuDatas[NextNumber]);
+ }
+ }
+ SetApState (CpuData, CpuStateIdle);
+ }
+ }
+}
+
+/**
+ Check if all APs are in state CpuStateSleeping.
+
+ Return TRUE if all APs are in the CpuStateSleeping state. Do not
+ check the state of the BSP or any disabled APs.
+
+ @retval TRUE All APs are in CpuStateSleeping state.
+ @retval FALSE One or more APs are not in CpuStateSleeping state.
+
+**/
+BOOLEAN
+CheckAllAPsSleeping (
+ VOID
+ )
+{
+ UINTN ProcessorNumber;
+ CPU_DATA_BLOCK *CpuData;
+
+ for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ //
+ // Skip Disabled processors
+ //
+ continue;
+ }
+
+ if (GetApState (CpuData) != CpuStateSleeping) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ If the timeout expires before all APs returns from Procedure,
+ we should forcibly terminate the executing AP and fill FailedList back
+ by StartupAllAPs().
+
+**/
+VOID
+ResetAllFailedAPs (
+ VOID
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ UINTN Number;
+ CPU_STATE CpuState;
+
+ if (mMpSystemData.FailedList != NULL) {
+ *mMpSystemData.FailedList = AllocatePool ((mMpSystemData.StartCount - mMpSystemData.FinishCount + 1) * sizeof(UINTN));
+ ASSERT (*mMpSystemData.FailedList != NULL);
+ }
+
+ for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
+ CpuData = &mMpSystemData.CpuDatas[Number];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ //
+ // Skip Disabled processors
+ //
+ continue;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
+ if (mMpSystemData.FailedList != NULL) {
+ (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;
+ }
+ ResetProcessorToIdleState (CpuData);
+ }
+ }
+
+ if (mMpSystemData.FailedList != NULL) {
+ (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex] = END_OF_CPU_LIST;
+ }
+}
+
+/**
+ 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;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *NumberOfProcessors = mMpSystemData.NumberOfProcessors;
+ *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ )
+{
+ if (ProcessorInfoBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ CopyMem (ProcessorInfoBuffer, &mMpSystemData.CpuDatas[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
+ return EFI_SUCCESS;
+}
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
+ mode, and the BSP returns from this service without waiting for APs. If a
+ non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled, then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Protocol does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. EFI services and protocols may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroseconds expires.
+
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
+ sequence needs to occur in a non-blocking execution mode:
+
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
+ invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
+ is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
+ the function specified by Procedure to be started on all the enabled APs,
+ and releases the BSP to continue with other tasks.
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ the state of the WaitEvent created in step 1.
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool() service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
+ prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] 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
+ )
+{
+ EFI_STATUS Status;
+ CPU_DATA_BLOCK *CpuData;
+ UINTN Number;
+ CPU_STATE APInitialState;
+ CPU_STATE CpuState;
+
+ CpuData = NULL;
+
+ if (FailedCpuList != NULL) {
+ *FailedCpuList = NULL;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (mMpSystemData.NumberOfProcessors == 1) {
+ return EFI_NOT_STARTED;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // temporarily stop checkAllAPsStatus for avoid resource dead-lock.
+ //
+ mStopCheckAllAPsStatus = TRUE;
+
+ for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
+ CpuData = &mMpSystemData.CpuDatas[Number];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ //
+ // Skip Disabled processors
+ //
+ continue;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ mMpSystemData.Procedure = Procedure;
+ mMpSystemData.ProcedureArgument = ProcedureArgument;
+ mMpSystemData.WaitEvent = WaitEvent;
+ mMpSystemData.Timeout = TimeoutInMicroseconds;
+ mMpSystemData.TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
+ mMpSystemData.FinishCount = 0;
+ mMpSystemData.StartCount = 0;
+ mMpSystemData.SingleThread = SingleThread;
+ mMpSystemData.FailedList = FailedCpuList;
+ mMpSystemData.FailedListIndex = 0;
+ APInitialState = CpuStateReady;
+
+ for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
+ CpuData = &mMpSystemData.CpuDatas[Number];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+
+ if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ //
+ // Skip Disabled processors
+ //
+ continue;
+ }
+
+ //
+ // Get APs prepared, and put failing APs into FailedCpuList
+ // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready
+ // state 1 by 1, until the previous 1 finished its task
+ // if not "SingleThread", all APs are put to ready state from the beginning
+ //
+ CpuState = GetApState (CpuData);
+ if (CpuState == CpuStateIdle ||
+ CpuState == CpuStateSleeping) {
+ mMpSystemData.StartCount++;
+
+ SetApState (CpuData, APInitialState);
+
+ if (APInitialState == CpuStateReady) {
+ SetApProcedure (CpuData, Procedure, ProcedureArgument);
+ //
+ // If this AP previous state is Sleeping, we should
+ // wake up this AP by sent a SIPI. and avoid
+ // re-involve the sleeping state. we must call
+ // SetApProcedure() first.
+ //
+ if (CpuState == CpuStateSleeping) {
+ ResetProcessorToIdleState (CpuData);
+ }
+ }
+
+ if (SingleThread) {
+ APInitialState = CpuStateBlocked;
+ }
+ }
+ }
+
+ mStopCheckAllAPsStatus = FALSE;
+
+ if (WaitEvent != NULL) {
+ //
+ // non blocking
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Blocking temporarily stop CheckAllAPsStatus()
+ //
+ mStopCheckAllAPsStatus = TRUE;
+
+ while (TRUE) {
+ CheckAndUpdateAllAPsToIdleState ();
+ if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ //
+ // task timeout
+ //
+ if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
+ ResetAllFailedAPs();
+ Status = EFI_TIMEOUT;
+ goto Done;
+ }
+
+ MicroSecondDelay (gPollInterval);
+ mMpSystemData.Timeout -= gPollInterval;
+ }
+
+Done:
+
+ return Status;
+}
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] 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
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ CPU_STATE CpuState;
+
+ CpuData = NULL;
+
+ if (Finished != NULL) {
+ *Finished = FALSE;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // temporarily stop checkAllAPsStatus for avoid resource dead-lock.
+ //
+ mStopCheckAllAPsStatus = TRUE;
+
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) ||
+ !TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
+ return EFI_NOT_READY;
+ }
+
+ SetApState (CpuData, CpuStateReady);
+
+ SetApProcedure (CpuData, Procedure, ProcedureArgument);
+ //
+ // If this AP previous state is Sleeping, we should
+ // wake up this AP by sent a SIPI. and avoid
+ // re-involve the sleeping state. we must call
+ // SetApProcedure() first.
+ //
+ if (CpuState == CpuStateSleeping) {
+ ResetProcessorToIdleState (CpuData);
+ }
+
+ CpuData->Timeout = TimeoutInMicroseconds;
+ CpuData->WaitEvent = WaitEvent;
+ CpuData->TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
+ CpuData->Finished = Finished;
+
+ mStopCheckAllAPsStatus = FALSE;
+
+ if (WaitEvent != NULL) {
+ //
+ // Non Blocking
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Blocking
+ //
+ while (TRUE) {
+ if (GetApState (CpuData) == CpuStateFinished) {
+ SetApState (CpuData, CpuStateIdle);
+ break;
+ }
+
+ if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
+ ResetProcessorToIdleState (CpuData);
+ return EFI_TIMEOUT;
+ }
+
+ MicroSecondDelay (gPollInterval);
+ CpuData->Timeout -= gPollInterval;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ //
+ // Current always return unsupported.
+ //
+ 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.
+
+ 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
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ BOOLEAN TempStopCheckState;
+ CPU_STATE CpuState;
+
+ CpuData = NULL;
+ TempStopCheckState = FALSE;
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // temporarily stop checkAllAPsStatus for initialize parameters.
+ //
+ if (!mStopCheckAllAPsStatus) {
+ mStopCheckAllAPsStatus = TRUE;
+ TempStopCheckState = TRUE;
+ }
+
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpuState = GetApState (CpuData);
+ if (CpuState != CpuStateIdle &&
+ CpuState != CpuStateSleeping) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EnableAP) {
+ if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) {
+ mMpSystemData.NumberOfEnabledProcessors++;
+ }
+ CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT);
+ } else {
+ if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
+ mMpSystemData.NumberOfEnabledProcessors--;
+ }
+ CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT);
+ }
+
+ if (HealthFlag != NULL) {
+ CpuStatusFlagAndNot (CpuData, (UINT32)~PROCESSOR_HEALTH_STATUS_BIT);
+ CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));
+ }
+
+ if (TempStopCheckState) {
+ mStopCheckAllAPsStatus = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[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
+ )
+{
+ UINTN Index;
+ UINT32 ProcessorId;
+
+ if (ProcessorNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProcessorId = GetApicId ();
+ for (Index = 0; Index < mMpSystemData.NumberOfProcessors; Index++) {
+ if (mMpSystemData.CpuDatas[Index].Info.ProcessorId == ProcessorId) {
+ break;
+ }
+ }
+
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+}
+
+/**
+ Terminate AP's task and set it to idle state.
+
+ This function terminates AP's task due to timeout by sending INIT-SIPI,
+ and sends it to idle state.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+
+**/
+VOID
+ResetProcessorToIdleState (
+ IN CPU_DATA_BLOCK *CpuData
+ )
+{
+ ResetApStackless ((UINT32)CpuData->Info.ProcessorId);
+}
+
+/**
+ Application Processors do loop routine
+ after switch to its own stack.
+
+ @param Context1 A pointer to the context to pass into the function.
+ @param Context2 A pointer to the context to pass into the function.
+
+**/
+VOID
+ProcessorToIdleState (
+ IN VOID *Context1, OPTIONAL
+ IN VOID *Context2 OPTIONAL
+ )
+{
+ UINTN ProcessorNumber;
+ CPU_DATA_BLOCK *CpuData;
+ EFI_AP_PROCEDURE Procedure;
+ volatile VOID *ProcedureArgument;
+
+ AsmApDoneWithCommonStack ();
+
+ while (!mAPsAlreadyInitFinished) {
+ CpuPause ();
+ }
+
+ WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+
+ //
+ // Avoid forcibly reset AP caused the AP got lock not release.
+ //
+ if (CpuData->LockSelf == (INTN) GetApicId ()) {
+ ReleaseSpinLock (&CpuData->CpuDataLock);
+ }
+
+ //
+ // Avoid forcibly reset AP caused the timeout AP State is not
+ // updated.
+ //
+ GetMpSpinLock (CpuData);
+ if (CpuData->State == CpuStateBusy) {
+ CpuData->Procedure = NULL;
+ }
+ CpuData->State = CpuStateIdle;
+ ReleaseMpSpinLock (CpuData);
+
+ while (TRUE) {
+ GetMpSpinLock (CpuData);
+ ProcedureArgument = CpuData->Parameter;
+ Procedure = CpuData->Procedure;
+ ReleaseMpSpinLock (CpuData);
+
+ if (Procedure != NULL) {
+ SetApState (CpuData, CpuStateBusy);
+
+ Procedure ((VOID*) ProcedureArgument);
+
+ GetMpSpinLock (CpuData);
+ CpuData->Procedure = NULL;
+ CpuData->State = CpuStateFinished;
+ ReleaseMpSpinLock (CpuData);
+ } else {
+ //
+ // if no procedure to execution, we simply put AP
+ // into sleeping state, and waiting BSP sent SIPI.
+ //
+ GetMpSpinLock (CpuData);
+ if (CpuData->State == CpuStateIdle) {
+ CpuData->State = CpuStateSleeping;
+ }
+ ReleaseMpSpinLock (CpuData);
+ }
+
+ if (GetApState (CpuData) == CpuStateSleeping) {
+ CpuSleep ();
+ }
+
+ CpuPause ();
+ }
+
+ CpuSleep ();
+ CpuDeadLoop ();
+}
+
+/**
+ Checks AP' status periodically.
+
+ This function is triggerred by timer perodically to check the
+ state of AP forStartupThisAP() executed in non-blocking mode.
+
+ @param Event Event triggered.
+ @param Context Parameter passed with the event.
+
+**/
+VOID
+EFIAPI
+CheckThisAPStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ CPU_STATE CpuState;
+
+ CpuData = (CPU_DATA_BLOCK *) Context;
+ if (CpuData->TimeoutActive) {
+ CpuData->Timeout -= gPollInterval;
+ }
+
+ CpuState = GetApState (CpuData);
+
+ if (CpuState == CpuStateFinished) {
+ if (CpuData->Finished) {
+ *CpuData->Finished = TRUE;
+ }
+ SetApState (CpuData, CpuStateIdle);
+ goto out;
+ }
+
+ if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
+ if (CpuState != CpuStateIdle &&
+ CpuData->Finished) {
+ *CpuData->Finished = FALSE;
+ }
+ ResetProcessorToIdleState (CpuData);
+ goto out;
+ }
+
+ return;
+
+out:
+ CpuData->TimeoutActive = FALSE;
+ gBS->SignalEvent (CpuData->WaitEvent);
+ CpuData->WaitEvent = NULL;
+}
+
+/**
+ Checks APs' status periodically.
+
+ This function is triggerred by timer perodically to check the
+ state of APs for StartupAllAPs() executed in non-blocking mode.
+
+ @param Event Event triggered.
+ @param Context Parameter passed with the event.
+
+**/
+VOID
+EFIAPI
+CheckAllAPsStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ UINTN Number;
+ EFI_STATUS Status;
+
+ if (mMpSystemData.TimeoutActive) {
+ mMpSystemData.Timeout -= gPollInterval;
+ }
+
+ if (mStopCheckAllAPsStatus) {
+ return;
+ }
+
+ //
+ // avoid next timer enter.
+ //
+ Status = gBS->SetTimer (
+ mMpSystemData.CheckAllAPsEvent,
+ TimerCancel,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (mMpSystemData.WaitEvent != NULL) {
+ CheckAndUpdateAllAPsToIdleState ();
+ //
+ // task timeout
+ //
+ if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
+ ResetAllFailedAPs();
+ //
+ // force exit
+ //
+ mMpSystemData.FinishCount = mMpSystemData.StartCount;
+ }
+
+ if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
+ goto EXIT;
+ }
+
+ mMpSystemData.TimeoutActive = FALSE;
+ gBS->SignalEvent (mMpSystemData.WaitEvent);
+ mMpSystemData.WaitEvent = NULL;
+ mStopCheckAllAPsStatus = TRUE;
+
+ goto EXIT;
+ }
+
+ //
+ // check each AP status for StartupThisAP
+ //
+ for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
+ CpuData = &mMpSystemData.CpuDatas[Number];
+ if (CpuData->WaitEvent) {
+ CheckThisAPStatus (NULL, (VOID *)CpuData);
+ }
+ }
+
+EXIT:
+ Status = gBS->SetTimer (
+ mMpSystemData.CheckAllAPsEvent,
+ TimerPeriodic,
+ EFI_TIMER_PERIOD_MICROSECONDS (100)
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Application Processor C code entry point.
+
+**/
+VOID
+EFIAPI
+ApEntryPointInC (
+ VOID
+ )
+{
+ VOID* TopOfApStack;
+ UINTN ProcessorNumber;
+
+ if (!mAPsAlreadyInitFinished) {
+ FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
+ TopOfApStack = (UINT8*)mApStackStart + gApStackSize;
+ mApStackStart = TopOfApStack;
+
+ //
+ // Store the Stack address, when reset the AP, We can found the original address.
+ //
+ mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack;
+ mMpSystemData.NumberOfProcessors++;
+ mMpSystemData.NumberOfEnabledProcessors++;
+ } else {
+ WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
+ //
+ // Get the original stack address.
+ //
+ TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack;
+ }
+
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
+ NULL,
+ NULL,
+ TopOfApStack);
+}
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects MP related data.
+
+ @param Bsp TRUE if the CPU is BSP
+ @param ProcessorNumber The specific processor number
+
+ @retval EFI_SUCCESS Data for the processor collected and filled in
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN Bsp,
+ IN UINTN ProcessorNumber
+ )
+{
+ CPU_DATA_BLOCK *CpuData;
+ UINT32 ProcessorId;
+
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ ProcessorId = GetApicId ();
+ CpuData->Info.ProcessorId = ProcessorId;
+ CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
+ if (Bsp) {
+ CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
+ }
+ CpuData->Info.Location.Package = ProcessorId;
+ CpuData->Info.Location.Core = 0;
+ CpuData->Info.Location.Thread = 0;
+ CpuData->State = Bsp ? CpuStateBusy : CpuStateIdle;
+
+ CpuData->Procedure = NULL;
+ CpuData->Parameter = NULL;
+ InitializeSpinLock (&CpuData->CpuDataLock);
+ CpuData->LockSelf = -1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Prepare the System Data.
+
+ @retval EFI_SUCCESS the System Data finished initilization.
+
+**/
+EFI_STATUS
+InitMpSystemData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));
+
+ mMpSystemData.NumberOfProcessors = 1;
+ mMpSystemData.NumberOfEnabledProcessors = 1;
+
+ mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber);
+ ASSERT(mMpSystemData.CpuDatas != NULL);
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CheckAllAPsStatus,
+ NULL,
+ &mMpSystemData.CheckAllAPsEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set timer to check all APs status.
+ //
+ Status = gBS->SetTimer (
+ mMpSystemData.CheckAllAPsEvent,
+ TimerPeriodic,
+ EFI_TIMER_PERIOD_MICROSECONDS (100)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // BSP
+ //
+ FillInProcessorInformation (TRUE, 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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;
+ UINT32 InitialLocalApicId;
+ CPU_DATA_BLOCK *CpuData;
+
+ 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 ((EFI_D_INFO, "Does not find any HOB stored CPU BIST information!\n"));
+ //
+ // Does not find any HOB stored BIST information
+ //
+ return;
+ }
+ }
+
+ while ((NumberOfData--) > 0) {
+ for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
+ CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+ InitialLocalApicId = (UINT32) CpuData->Info.ProcessorId;
+ if (InitialLocalApicId == CpuInstance[NumberOfData].CpuLocation) {
+ //
+ // Update CPU health status for MP Services Protocol according to BIST data.
+ //
+ if (CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags.Uint32 != 0) {
+ CpuData->Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
+ //
+ // 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)
+ );
+ }
+ }
+ }
+ }
+}
+
+/**
+ Callback function for ExitBootServices.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+ExitBootServicesCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Avoid APs access invalid buff datas which allocated by BootServices,
+ // so we send INIT IPI to APs to let them wait for SIPI state.
+ //
+ SendInitIpiAllExcludingSelf ();
+}
+
+/**
+ 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);
+}
+
+/**
+ Initialize Multi-processor support.
+
+**/
+VOID
+InitializeMpSupport (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ MTRR_SETTINGS MtrrSettings;
+ UINTN Timeout;
+
+ gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ if (gMaxLogicalProcessorNumber < 1) {
+ DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
+ return;
+ }
+
+
+
+ InitMpSystemData ();
+
+ //
+ // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
+ //
+ if (gMaxLogicalProcessorNumber > 1) {
+
+ gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
+ ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);
+
+ mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
+ ASSERT (mApStackStart != NULL);
+
+ //
+ // the first buffer of stack size used for common stack, when the amount of AP
+ // more than 1, we should never free the common stack which maybe used for AP reset.
+ //
+ mCommonStack = mApStackStart;
+ mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;
+ mApStackStart = mTopOfApCommonStack;
+
+ PrepareAPStartupCode ();
+
+ StartApsStackless ();
+ }
+
+ DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors));
+ if (mMpSystemData.NumberOfProcessors == 1) {
+ FreeApStartupCode ();
+ if (mCommonStack != NULL) {
+ FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
+ }
+ }
+
+ mMpSystemData.CpuDatas = ReallocatePool (
+ sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber,
+ sizeof (CPU_DATA_BLOCK) * mMpSystemData.NumberOfProcessors,
+ mMpSystemData.CpuDatas);
+
+ //
+ // Release all APs to complete initialization and enter idle loop
+ //
+ mAPsAlreadyInitFinished = TRUE;
+
+ //
+ // Wait for all APs to enter idle loop.
+ //
+ Timeout = 0;
+ do {
+ if (CheckAllAPsSleeping ()) {
+ break;
+ }
+ MicroSecondDelay (gPollInterval);
+ Timeout += gPollInterval;
+ } while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+ ASSERT (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+
+ //
+ // Update CPU healthy information from Guided HOB
+ //
+ CollectBistDataFromHob ();
+
+ //
+ // Synchronize MTRR settings to APs.
+ //
+ MtrrGetAllMtrrs (&MtrrSettings);
+ Status = mMpServicesTemplate.StartupAllAPs (
+ &mMpServicesTemplate, // This
+ SetMtrrsFromBuffer, // Procedure
+ TRUE, // SingleThread
+ NULL, // WaitEvent
+ 0, // TimeoutInMicrosecsond
+ &MtrrSettings, // ProcedureArgument
+ NULL // FailedCpuList
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_STARTED);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mMpServiceHandle,
+ &gEfiMpServiceProtocolGuid, &mMpServicesTemplate,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (mMpSystemData.NumberOfProcessors > 1 && mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
+ if (mApStackStart != NULL) {
+ FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
+ (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *
+ gApStackSize));
+ }
+ }
+
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ ExitBootServicesCallback,
+ NULL,
+ &mExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+}
diff --git a/Core/UefiCpuPkg/CpuDxe/CpuMp.h b/Core/UefiCpuPkg/CpuDxe/CpuMp.h
new file mode 100644
index 0000000000..503f3ae944
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -0,0 +1,660 @@
+/** @file
+ CPU DXE MP support
+
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_MP_H_
+#define _CPU_MP_H_
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
+#include <Protocol/MpService.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/HobLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+/**
+ Initialize Multi-processor support.
+
+**/
+VOID
+InitializeMpSupport (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *STACKLESS_AP_ENTRY_POINT)(
+ VOID
+ );
+
+/**
+ Starts the Application Processors and directs them to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @retval EFI_SUCCESS The APs were started
+
+**/
+EFI_STATUS
+StartApsStackless (
+ VOID
+ );
+
+/**
+ The AP entry point that the Startup-IPI target code will jump to.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+**/
+VOID
+EFIAPI
+AsmApEntryPoint (
+ VOID
+ );
+
+/**
+ Releases the lock preventing other APs from using the shared AP
+ stack.
+
+ Once the AP has transitioned to using a new stack, it can call this
+ function to allow another AP to proceed with using the shared stack.
+
+**/
+VOID
+EFIAPI
+AsmApDoneWithCommonStack (
+ VOID
+ );
+
+typedef enum {
+ CpuStateIdle,
+ CpuStateBlocked,
+ CpuStateReady,
+ CpuStateBusy,
+ CpuStateFinished,
+ CpuStateSleeping
+} CPU_STATE;
+
+/**
+ Define Individual Processor Data block.
+
+**/
+typedef struct {
+ EFI_PROCESSOR_INFORMATION Info;
+ SPIN_LOCK CpuDataLock;
+ INTN LockSelf;
+ volatile CPU_STATE State;
+
+ volatile EFI_AP_PROCEDURE Procedure;
+ volatile VOID* Parameter;
+ BOOLEAN *Finished;
+ INTN Timeout;
+ EFI_EVENT WaitEvent;
+ BOOLEAN TimeoutActive;
+ EFI_EVENT CheckThisAPEvent;
+ VOID *TopOfStack;
+} CPU_DATA_BLOCK;
+
+/**
+ Define MP data block which consumes individual processor block.
+
+**/
+typedef struct {
+ CPU_DATA_BLOCK *CpuDatas;
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
+
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcedureArgument;
+ UINTN StartCount;
+ UINTN FinishCount;
+ BOOLEAN SingleThread;
+ UINTN **FailedList;
+ UINTN FailedListIndex;
+ INTN Timeout;
+ EFI_EVENT WaitEvent;
+ BOOLEAN TimeoutActive;
+ EFI_EVENT CheckAllAPsEvent;
+} MP_SYSTEM_DATA;
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects MP related data.
+
+ @param Bsp TRUE if the CPU is BSP
+ @param ProcessorNumber The specific processor number
+
+ @retval EFI_SUCCESS Data for the processor collected and filled in
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN Bsp,
+ IN UINTN ProcessorNumber
+ );
+
+/**
+ 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 TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool() service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
+ prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] 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
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] 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_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+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
+ );
+
+/**
+ Terminate AP's task and set it to idle state.
+
+ This function terminates AP's task due to timeout by sending INIT-SIPI,
+ and sends it to idle state.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+
+**/
+VOID
+ResetProcessorToIdleState (
+ IN CPU_DATA_BLOCK *CpuData
+ );
+
+/**
+ Prepares Startup Code for APs.
+ This function prepares Startup Code for APs.
+
+ @retval EFI_SUCCESS The APs were started
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate memory to start APs
+
+**/
+EFI_STATUS
+PrepareAPStartupCode (
+ VOID
+ );
+
+/**
+ Free the code buffer of startup AP.
+
+**/
+VOID
+FreeApStartupCode (
+ VOID
+ );
+
+/**
+ Resets the Application Processor and directs it to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @param ProcessorId the AP of ProcessorId was reset
+**/
+VOID
+ResetApStackless (
+ IN UINT32 ProcessorId
+ );
+
+/**
+ 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
+ );
+
+#endif // _CPU_MP_H_
+
diff --git a/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
new file mode 100644
index 0000000000..e034bc2e2e
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* 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
+
+#------------------------------------------------------------------------------
+# 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
+
+#END
+
diff --git a/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm b/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
new file mode 100644
index 0000000000..7f8f0d6f3a
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
@@ -0,0 +1,58 @@
+ TITLE CpuAsm.asm:
+;------------------------------------------------------------------------------
+;*
+;* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+;* This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* 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
+
+;------------------------------------------------------------------------------
+; 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
+
+
+END
diff --git a/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm b/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
new file mode 100644
index 0000000000..09579f251e
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
@@ -0,0 +1,76 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+.686
+.xmm
+.model flat, C
+
+extern mTopOfApCommonStack:DWORD
+extern ApEntryPointInC:PROC
+
+.code
+
+;
+; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
+;
+ApStackLock dd 0
+
+;.code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+; VOID
+; );
+;------------------------------------------------------------------------------
+AsmApEntryPoint PROC
+
+ cli
+AsmApEntryPointAcquireLock:
+lock bts dword ptr [ApStackLock], 0
+ pause
+ jc AsmApEntryPointAcquireLock
+
+ mov esp, [mTopOfApCommonStack]
+ call ApEntryPointInC
+
+ cli
+
+lock btc dword ptr [ApStackLock], 0
+
+ mov eax, 100h
+AsmApEntryPointShareLock:
+ pause
+ dec eax
+ jnz AsmApEntryPointShareLock
+
+ jmp AsmApEntryPoint
+
+AsmApEntryPoint ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+; VOID
+; );
+;------------------------------------------------------------------------------
+AsmApDoneWithCommonStack PROC PUBLIC
+
+lock btc dword ptr [ApStackLock], 0
+ ret
+
+AsmApDoneWithCommonStack ENDP
+
+END
diff --git a/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm b/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
new file mode 100644
index 0000000000..c47cdcef54
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+extern ASM_PFX(mTopOfApCommonStack)
+extern ASM_PFX(ApEntryPointInC)
+
+SECTION .data
+
+;
+; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
+;
+ApStackLock:
+ dd 0
+
+SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+ cli
+AsmApEntryPointAcquireLock:
+lock bts dword [ApStackLock], 0
+ pause
+ jc AsmApEntryPointAcquireLock
+
+ mov esp, [ASM_PFX(mTopOfApCommonStack)]
+ call ASM_PFX(ApEntryPointInC)
+
+ cli
+
+lock btc dword [ApStackLock], 0
+
+ mov eax, 0x100
+AsmApEntryPointShareLock:
+ pause
+ dec eax
+ jnz AsmApEntryPointShareLock
+
+ jmp ASM_PFX(AsmApEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btc dword [ApStackLock], 0
+ ret
+
diff --git a/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.S b/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
new file mode 100644
index 0000000000..e82cadf369
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
@@ -0,0 +1,60 @@
+# TITLE CpuAsm.S:
+
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* 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
+
+
+#------------------------------------------------------------------------------
+# VOID
+# SetCodeSelector (
+# UINT16 Selector
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(SetCodeSelector)
+ASM_PFX(SetCodeSelector):
+ subq $0x10, %rsp
+ leaq L_setCodeSelectorLongJump(%rip), %rax
+ movq %rax, (%rsp)
+ movw %cx, 4(%rsp)
+ .byte 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp
+L_setCodeSelectorLongJump:
+ addq $0x10, %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
+
+#text ENDS
+
+#END
+
+
diff --git a/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm b/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
new file mode 100644
index 0000000000..c71b06a81e
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
@@ -0,0 +1,54 @@
+ TITLE CpuAsm.asm:
+;------------------------------------------------------------------------------
+;*
+;* Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+;* This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* 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
+
+;------------------------------------------------------------------------------
+; VOID
+; SetCodeSelector (
+; UINT16 Selector
+; );
+;------------------------------------------------------------------------------
+SetCodeSelector PROC PUBLIC
+ sub rsp, 0x10
+ lea rax, setCodeSelectorLongJump
+ mov [rsp], rax
+ mov [rsp+4], cx
+ jmp fword ptr [rsp]
+setCodeSelectorLongJump:
+ add rsp, 0x10
+ 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
+
+END
+
diff --git a/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.asm b/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.asm
new file mode 100644
index 0000000000..308de51330
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.asm
@@ -0,0 +1,76 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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 <Base.h>
+
+extern ASM_PFX(mTopOfApCommonStack):QWORD
+extern ASM_PFX(ApEntryPointInC):PROC
+
+.data
+
+;
+; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
+;
+ApStackLock:
+ dd 0
+
+.code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+; VOID
+; );
+;------------------------------------------------------------------------------
+ASM_PFX(AsmApEntryPoint) PROC PUBLIC
+
+ cli
+AsmApEntryPointAcquireLock:
+lock bts dword ptr [ApStackLock], 0
+ pause
+ jc AsmApEntryPointAcquireLock
+
+ mov rsp, [ASM_PFX(mTopOfApCommonStack)]
+ call ASM_PFX(ApEntryPointInC)
+
+ cli
+
+lock btc dword ptr [ApStackLock], 0
+
+ mov eax, 100h
+AsmApEntryPointShareLock:
+ pause
+ dec eax
+ jnz AsmApEntryPointShareLock
+
+ jmp ASM_PFX(AsmApEntryPoint)
+
+ASM_PFX(AsmApEntryPoint) ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+; VOID
+; );
+;------------------------------------------------------------------------------
+ASM_PFX(AsmApDoneWithCommonStack) PROC PUBLIC
+
+lock btc dword ptr [ApStackLock], 0
+ ret
+
+ASM_PFX(AsmApDoneWithCommonStack) ENDP
+
+END
+
diff --git a/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm b/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
new file mode 100644
index 0000000000..e3dc248002
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+extern ASM_PFX(mTopOfApCommonStack)
+extern ASM_PFX(ApEntryPointInC)
+
+DEFAULT REL
+
+SECTION .data
+
+;
+; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
+;
+ApStackLock:
+ dd 0
+
+SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApEntryPoint (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApEntryPoint)
+ASM_PFX(AsmApEntryPoint):
+ cli
+AsmApEntryPointAcquireLock:
+lock bts dword [ApStackLock], 0
+ pause
+ jc AsmApEntryPointAcquireLock
+
+ mov rsp, [ASM_PFX(mTopOfApCommonStack)]
+ call ASM_PFX(ApEntryPointInC)
+
+ cli
+
+lock btc dword [ApStackLock], 0
+
+ mov eax, 0x100
+AsmApEntryPointShareLock:
+ pause
+ dec eax
+ jnz AsmApEntryPointShareLock
+
+ jmp ASM_PFX(AsmApEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApDoneWithCommonStack (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApDoneWithCommonStack)
+ASM_PFX(AsmApDoneWithCommonStack):
+lock btc dword [ApStackLock], 0
+ ret
+
diff --git a/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c
new file mode 100644
index 0000000000..3d8a799230
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.c
@@ -0,0 +1,536 @@
+/** @file
+ Produces the CPU I/O 2 Protocol.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "CpuIo2Dxe.h"
+
+//
+// Handle for the CPU I/O 2 Protocol
+//
+EFI_HANDLE mHandle = NULL;
+
+//
+// CPU I/O 2 Protocol instance
+//
+EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
+ {
+ CpuMemoryServiceRead,
+ CpuMemoryServiceWrite
+ },
+ {
+ CpuIoServiceRead,
+ CpuIoServiceWrite
+ }
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mInStride[] = {
+ 1, // EfiCpuIoWidthUint8
+ 2, // EfiCpuIoWidthUint16
+ 4, // EfiCpuIoWidthUint32
+ 8, // EfiCpuIoWidthUint64
+ 0, // EfiCpuIoWidthFifoUint8
+ 0, // EfiCpuIoWidthFifoUint16
+ 0, // EfiCpuIoWidthFifoUint32
+ 0, // EfiCpuIoWidthFifoUint64
+ 1, // EfiCpuIoWidthFillUint8
+ 2, // EfiCpuIoWidthFillUint16
+ 4, // EfiCpuIoWidthFillUint32
+ 8 // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mOutStride[] = {
+ 1, // EfiCpuIoWidthUint8
+ 2, // EfiCpuIoWidthUint16
+ 4, // EfiCpuIoWidthUint32
+ 8, // EfiCpuIoWidthUint64
+ 1, // EfiCpuIoWidthFifoUint8
+ 2, // EfiCpuIoWidthFifoUint16
+ 4, // EfiCpuIoWidthFifoUint32
+ 8, // EfiCpuIoWidthFifoUint64
+ 0, // EfiCpuIoWidthFillUint8
+ 0, // EfiCpuIoWidthFillUint16
+ 0, // EfiCpuIoWidthFillUint32
+ 0 // EfiCpuIoWidthFillUint64
+};
+
+/**
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The parameters for this request pass the checks.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+CpuIoCheckParameter (
+ IN BOOLEAN MmioOperation,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ UINT64 MaxCount;
+ UINT64 Limit;
+
+ //
+ // Check to see if Buffer is NULL
+ //
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Width is in the valid range
+ //
+ if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // For FIFO type, the target address won't increase during the access,
+ // so treat Count as 1
+ //
+ if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
+ Count = 1;
+ }
+
+ //
+ // Check to see if Width is in the valid range for I/O Port operations
+ //
+ Width = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Address is aligned
+ //
+ if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // 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
+ // 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
+ // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+ //
+ Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+ if (Count == 0) {
+ if (Address > Limit) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ MaxCount = RShiftU64 (Limit, Width);
+ if (MaxCount < (Count - 1)) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Check to see if Buffer is 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;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint64) {
+ *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint64) {
+ MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ *Uint8Buffer = IoRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ //
+ // Make sure the parameters are valid
+ //
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ IoWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ 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] 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
+CpuIo2Initialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h
new file mode 100644
index 0000000000..7d00da16f4
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.h
@@ -0,0 +1,225 @@
+/** @file
+ Internal include file for the CPU I/O 2 Protocol.
+
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_IO2_DXE_H_
+#define _CPU_IO2_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/CpuIo2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define MAX_IO_PORT_ADDRESS 0xFFFF
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ 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
+ be handled by the driver.
+
+ 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
+ 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
+ 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
+ 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.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @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,
+ and Count is not valid for this PI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
new file mode 100644
index 0000000000..8ef8b3d31c
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
@@ -0,0 +1,51 @@
+## @file
+# Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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 IPF 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/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni
new file mode 100644
index 0000000000..59456fb3e5
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.uni
@@ -0,0 +1,22 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni
new file mode 100644
index 0000000000..655da485df
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Dxe/CpuIo2DxeExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// CpuIo2Dxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPU I/O v2 DXE Driver"
+
+
diff --git a/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c
new file mode 100644
index 0000000000..7b1ad37515
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c
@@ -0,0 +1,413 @@
+/** @file
+ Produces the SMM CPU I/O Protocol.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "CpuIo2Smm.h"
+
+//
+// Handle for the SMM CPU I/O Protocol
+//
+EFI_HANDLE mHandle = NULL;
+
+//
+// SMM CPU I/O Protocol instance
+//
+EFI_SMM_CPU_IO2_PROTOCOL mSmmCpuIo2 = {
+ {
+ CpuMemoryServiceRead,
+ CpuMemoryServiceWrite
+ },
+ {
+ CpuIoServiceRead,
+ CpuIoServiceWrite
+ }
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mStride[] = {
+ 1, // SMM_IO_UINT8
+ 2, // SMM_IO_UINT16
+ 4, // SMM_IO_UINT32
+ 8 // SMM_IO_UINT64
+};
+
+/**
+ Check parameters to a SMM CPU I/O Protocol service request.
+
+ @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] 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
+ 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 (
+ IN BOOLEAN MmioOperation,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ UINT64 MaxCount;
+ UINT64 Limit;
+
+ //
+ // Check to see if Buffer is NULL
+ //
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Width is in the valid range
+ //
+ if ((UINT32)Width > SMM_IO_UINT64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Width is in the valid range for I/O Port operations
+ //
+ if (!MmioOperation && (Width == SMM_IO_UINT64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // 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
+ // 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
+ // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+ //
+ Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+ if (Count == 0) {
+ if (Address > Limit) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ MaxCount = RShiftU64 (Limit, Width);
+ if (MaxCount < (Count - 1)) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Check to see if Address is aligned
+ //
+ if ((Address & (UINT64)(mStride[Width] - 1)) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Stride;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ Stride = mStride[Width];
+ for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+ if (Width == SMM_IO_UINT8) {
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ } else if (Width == SMM_IO_UINT16) {
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ } else if (Width == SMM_IO_UINT32) {
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ } else if (Width == SMM_IO_UINT64) {
+ *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Stride;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ Stride = mStride[Width];
+ for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+ if (Width == SMM_IO_UINT8) {
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (Width == SMM_IO_UINT16) {
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (Width == SMM_IO_UINT32) {
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ } else if (Width == SMM_IO_UINT64) {
+ MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Stride;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ Stride = mStride[Width];
+ for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+ if (Width == SMM_IO_UINT8) {
+ *Uint8Buffer = IoRead8 ((UINTN)Address);
+ } else if (Width == SMM_IO_UINT16) {
+ *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
+ } else if (Width == SMM_IO_UINT32) {
+ *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Stride;
+ UINT8 *Uint8Buffer;
+
+ //
+ // Make sure the parameters are valid
+ //
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ Stride = mStride[Width];
+ for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+ if (Width == SMM_IO_UINT8) {
+ IoWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (Width == SMM_IO_UINT16) {
+ IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (Width == SMM_IO_UINT32) {
+ IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The module Entry Point SmmCpuIoProtocol driver
+
+ @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
+SmmCpuIo2Initialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Copy the SMM CPU I/O Protocol instance into the System Management System Table
+ //
+ CopyMem (&gSmst->SmmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2));
+
+ //
+ // Install the SMM CPU I/O Protocol into the SMM protocol database
+ //
+ Status = gSmst->SmmInstallProtocolInterface (
+ &mHandle,
+ &gEfiSmmCpuIo2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmCpuIo2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h
new file mode 100644
index 0000000000..5a092594d7
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h
@@ -0,0 +1,162 @@
+/** @file
+ Internal include file for the SMM CPU I/O Protocol.
+
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_IO2_SMM_H_
+#define _CPU_IO2_SMM_H_
+
+#include <PiSmm.h>
+
+#include <Protocol/SmmCpuIo2.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#define MAX_IO_PORT_ADDRESS 0xFFFF
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ 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,
+ 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] 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
+ 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
+ lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
new file mode 100644
index 0000000000..d7c98f67c0
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
@@ -0,0 +1,52 @@
+## @file
+# 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.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# 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
+ 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/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni
new file mode 100644
index 0000000000..c3a212b1e7
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.uni
@@ -0,0 +1,21 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni
new file mode 100644
index 0000000000..b1b82b03b7
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIo2Smm/CpuIo2SmmExtra.uni
@@ -0,0 +1,19 @@
+// /** @file
+// CpuIo2Smm Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPU I/O v2 SMM Driver"
+
+
diff --git a/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.c b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.c
new file mode 100644
index 0000000000..3c5c8a74b3
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.c
@@ -0,0 +1,864 @@
+/** @file
+ Produces the CPU I/O PPI.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "CpuIoPei.h"
+
+//
+// Instance of CPU I/O PPI
+//
+EFI_PEI_CPU_IO_PPI gCpuIoPpi = {
+ {
+ CpuMemoryServiceRead,
+ CpuMemoryServiceWrite
+ },
+ {
+ CpuIoServiceRead,
+ CpuIoServiceWrite
+ },
+ CpuIoRead8,
+ CpuIoRead16,
+ CpuIoRead32,
+ CpuIoRead64,
+ CpuIoWrite8,
+ CpuIoWrite16,
+ CpuIoWrite32,
+ CpuIoWrite64,
+ CpuMemRead8,
+ CpuMemRead16,
+ CpuMemRead32,
+ CpuMemRead64,
+ CpuMemWrite8,
+ CpuMemWrite16,
+ CpuMemWrite32,
+ CpuMemWrite64
+};
+
+//
+// PPI Descriptor used to install the CPU I/O PPI
+//
+EFI_PEI_PPI_DESCRIPTOR gPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiCpuIoPpiInstalledGuid,
+ NULL
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mInStride[] = {
+ 1, // EfiPeiCpuIoWidthUint8
+ 2, // EfiPeiCpuIoWidthUint16
+ 4, // EfiPeiCpuIoWidthUint32
+ 8, // EfiPeiCpuIoWidthUint64
+ 0, // EfiPeiCpuIoWidthFifoUint8
+ 0, // EfiPeiCpuIoWidthFifoUint16
+ 0, // EfiPeiCpuIoWidthFifoUint32
+ 0, // EfiPeiCpuIoWidthFifoUint64
+ 1, // EfiPeiCpuIoWidthFillUint8
+ 2, // EfiPeiCpuIoWidthFillUint16
+ 4, // EfiPeiCpuIoWidthFillUint32
+ 8 // EfiPeiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mOutStride[] = {
+ 1, // EfiPeiCpuIoWidthUint8
+ 2, // EfiPeiCpuIoWidthUint16
+ 4, // EfiPeiCpuIoWidthUint32
+ 8, // EfiPeiCpuIoWidthUint64
+ 1, // EfiPeiCpuIoWidthFifoUint8
+ 2, // EfiPeiCpuIoWidthFifoUint16
+ 4, // EfiPeiCpuIoWidthFifoUint32
+ 8, // EfiPeiCpuIoWidthFifoUint64
+ 0, // EfiPeiCpuIoWidthFillUint8
+ 0, // EfiPeiCpuIoWidthFillUint16
+ 0, // EfiPeiCpuIoWidthFillUint32
+ 0 // EfiPeiCpuIoWidthFillUint64
+};
+
+/**
+ Check parameters to a CPU I/O PPI service request.
+
+ @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
+ @param[in] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[in] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+CpuIoCheckParameter (
+ IN BOOLEAN MmioOperation,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ UINT64 MaxCount;
+ UINT64 Limit;
+
+ //
+ // Check to see if Buffer is NULL
+ //
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Width is in the valid range
+ //
+ if ((UINT32)Width >= EfiPeiCpuIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // For FIFO type, the target address won't increase during the access,
+ // so treat Count as 1
+ //
+ if (Width >= EfiPeiCpuIoWidthFifoUint8 && Width <= EfiPeiCpuIoWidthFifoUint64) {
+ Count = 1;
+ }
+
+ //
+ // Check to see if Width is in the valid range for I/O Port operations
+ //
+ Width = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
+ if (!MmioOperation && (Width == EfiPeiCpuIoWidthUint64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // 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
+ // 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
+ // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+ //
+ Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+ if (Count == 0) {
+ if (Address > Limit) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ MaxCount = RShiftU64 (Limit, Width);
+ if (MaxCount < (Count - 1)) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads memory-mapped registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[out] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
+ BOOLEAN Aligned;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
+ Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiPeiCpuIoWidthUint8) {
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
+ if (Aligned) {
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ } else {
+ WriteUnaligned16 ((UINT16 *)Uint8Buffer, MmioRead16 ((UINTN)Address));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
+ if (Aligned) {
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ } else {
+ WriteUnaligned32 ((UINT32 *)Uint8Buffer, MmioRead32 ((UINTN)Address));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {
+ if (Aligned) {
+ *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+ } else {
+ WriteUnaligned64 ((UINT64 *)Uint8Buffer, MmioRead64 ((UINTN)Address));
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Writes memory-mapped registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[in] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
+ BOOLEAN Aligned;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
+ Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiPeiCpuIoWidthUint8) {
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
+ if (Aligned) {
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else {
+ MmioWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
+ if (Aligned) {
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ } else {
+ MmioWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {
+ if (Aligned) {
+ MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+ } else {
+ MmioWrite64 ((UINTN)Address, ReadUnaligned64 ((UINT64 *)Uint8Buffer));
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads I/O registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[out] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
+ BOOLEAN Aligned;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
+ Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiPeiCpuIoWidthUint8) {
+ *Uint8Buffer = IoRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
+ if (Aligned) {
+ *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
+ } else {
+ WriteUnaligned16 ((UINT16 *)Uint8Buffer, IoRead16 ((UINTN)Address));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
+ if (Aligned) {
+ *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
+ } else {
+ WriteUnaligned32 ((UINT32 *)Uint8Buffer, IoRead32 ((UINTN)Address));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write I/O registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[in] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth;
+ BOOLEAN Aligned;
+ UINT8 *Uint8Buffer;
+
+ //
+ // Make sure the parameters are valid
+ //
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
+ Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
+ for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiPeiCpuIoWidthUint8) {
+ IoWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
+ if (Aligned) {
+ IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else {
+ IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
+ }
+ } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
+ if (Aligned) {
+ IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ } else {
+ IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 8-bit I/O read operations.
+
+ @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.
+
+ @return An 8-bit value returned from the I/O space.
+**/
+UINT8
+EFIAPI
+CpuIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return IoRead8 ((UINTN)Address);
+}
+
+/**
+ 16-bit I/O read operations.
+
+ @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.
+
+ @return A 16-bit value returned from the I/O space.
+
+**/
+UINT16
+EFIAPI
+CpuIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return IoRead16 ((UINTN)Address);
+}
+
+/**
+ 32-bit I/O read operations.
+
+ @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.
+
+ @return A 32-bit value returned from the I/O space.
+
+**/
+UINT32
+EFIAPI
+CpuIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return IoRead32 ((UINTN)Address);
+}
+
+/**
+ 64-bit I/O read operations.
+
+ @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.
+
+ @return A 64-bit value returned from the I/O space.
+
+**/
+UINT64
+EFIAPI
+CpuIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return IoRead64 ((UINTN)Address);
+}
+
+/**
+ 8-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+ )
+{
+ IoWrite8 ((UINTN)Address, Data);
+}
+
+/**
+ 16-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+ )
+{
+ IoWrite16 ((UINTN)Address, Data);
+}
+
+/**
+ 32-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+ )
+{
+ IoWrite32 ((UINTN)Address, Data);
+}
+
+/**
+ 64-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+ )
+{
+ IoWrite64 ((UINTN)Address, Data);
+}
+
+/**
+ 8-bit memory read operations.
+
+ @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.
+
+ @return An 8-bit value returned from the memory space.
+
+**/
+UINT8
+EFIAPI
+CpuMemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return MmioRead8 ((UINTN)Address);
+}
+
+/**
+ 16-bit memory read operations.
+
+ @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.
+
+ @return A 16-bit value returned from the memory space.
+
+**/
+UINT16
+EFIAPI
+CpuMemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return MmioRead16 ((UINTN)Address);
+}
+
+/**
+ 32-bit memory read operations.
+
+ @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.
+
+ @return A 32-bit value returned from the memory space.
+
+**/
+UINT32
+EFIAPI
+CpuMemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return MmioRead32 ((UINTN)Address);
+}
+
+/**
+ 64-bit memory read operations.
+
+ @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.
+
+ @return A 64-bit value returned from the memory space.
+
+**/
+UINT64
+EFIAPI
+CpuMemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ )
+{
+ return MmioRead64 ((UINTN)Address);
+}
+
+/**
+ 8-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+ )
+{
+ MmioWrite8 ((UINTN)Address, Data);
+}
+
+/**
+ 16-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+ )
+{
+ MmioWrite16 ((UINTN)Address, Data);
+}
+
+/**
+ 32-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+ )
+{
+ MmioWrite32 ((UINTN)Address, Data);
+}
+
+/**
+ 64-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+ )
+{
+ MmioWrite64 ((UINTN)Address, Data);
+}
+
+/**
+ The Entry point of the CPU I/O PEIM
+
+ 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
+
+ @retval EFI_SUCCESS CPU I/O PPI successfully installed
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // 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));
+ } else {
+ Status = PeiServicesInstallPpi (&gPpiList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.h b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.h
new file mode 100644
index 0000000000..052f0e3d0e
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.h
@@ -0,0 +1,448 @@
+/** @file
+ Internal include file for the CPU I/O PPI.
+
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_IO2_PEI_H_
+#define _CPU_IO2_PEI_H_
+
+#include <PiDxe.h>
+
+#include <Ppi/CpuIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+
+#define MAX_IO_PORT_ADDRESS 0xFFFF
+
+/**
+ Reads memory-mapped registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[out] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Writes memory-mapped registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[in] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ Reads I/O registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[out] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Write I/O registers.
+
+ @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] Width The width of the access. Enumerated in bytes.
+ @param[in] Address The physical address of the access.
+ @param[in] Count The number of accesses to perform.
+ @param[in] Buffer A pointer to the buffer of data.
+
+ @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,
+ and Count is not valid for this EFI system.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ 8-bit I/O read operations.
+
+ @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.
+
+ @return An 8-bit value returned from the I/O space.
+**/
+UINT8
+EFIAPI
+CpuIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 16-bit I/O read operations.
+
+ @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.
+
+ @return A 16-bit value returned from the I/O space.
+
+**/
+UINT16
+EFIAPI
+CpuIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 32-bit I/O read operations.
+
+ @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.
+
+ @return A 32-bit value returned from the I/O space.
+
+**/
+UINT32
+EFIAPI
+CpuIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 64-bit I/O read operations.
+
+ @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.
+
+ @return A 64-bit value returned from the I/O space.
+
+**/
+UINT64
+EFIAPI
+CpuIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 8-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+ );
+
+/**
+ 16-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+ );
+
+/**
+ 32-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+ );
+
+/**
+ 64-bit I/O write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+ );
+
+/**
+ 8-bit memory read operations.
+
+ @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.
+
+ @return An 8-bit value returned from the memory space.
+
+**/
+UINT8
+EFIAPI
+CpuMemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 16-bit memory read operations.
+
+ @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.
+
+ @return A 16-bit value returned from the memory space.
+
+**/
+UINT16
+EFIAPI
+CpuMemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 32-bit memory read operations.
+
+ @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.
+
+ @return A 32-bit value returned from the memory space.
+
+**/
+UINT32
+EFIAPI
+CpuMemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 64-bit memory read operations.
+
+ @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.
+
+ @return A 64-bit value returned from the memory space.
+
+**/
+UINT64
+EFIAPI
+CpuMemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+ );
+
+/**
+ 8-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+ );
+
+/**
+ 16-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+ );
+
+/**
+ 32-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+ );
+
+/**
+ 64-bit memory write operations.
+
+ @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.
+ @param[in] Data The data to write.
+
+**/
+VOID
+EFIAPI
+CpuMemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.inf b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.inf
new file mode 100644
index 0000000000..b72ad6bfaf
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.inf
@@ -0,0 +1,51 @@
+## @file
+# Produces the CPU I/O PPI by using the services of the I/O Library.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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 IPF 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/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.uni b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.uni
new file mode 100644
index 0000000000..0d8a14ef12
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIoPei/CpuIoPei.uni
@@ -0,0 +1,22 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni b/Core/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni
new file mode 100644
index 0000000000..cd1f53a0cc
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuIoPei/CpuIoPeiExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// CpuIoPei Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPU I/O PEI Module"
+
+
diff --git a/Core/UefiCpuPkg/CpuMpPei/CpuBist.c b/Core/UefiCpuPkg/CpuMpPei/CpuBist.c
new file mode 100644
index 0000000000..56292452a9
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuBist.c
@@ -0,0 +1,263 @@
+/** @file
+ Update and publish processors' BIST information.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 "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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN BistInformationSize;
+ UINTN CpuIndex;
+ EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
+
+ PeiCpuMpData = GetMpHobData ();
+
+ BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
+ sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount;
+ //
+ // return the information size if input buffer size is too small
+ //
+ if ((*StructureSize) < (UINT64) BistInformationSize) {
+ *StructureSize = (UINT64) BistInformationSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount;
+ CpuInstance = PlatformInformationRecord2->CpuInstance;
+ for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) {
+ CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId;
+ CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health;
+ }
+
+ 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
+
+ @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
+ )
+{
+ 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;
+ 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
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+
+**/
+VOID
+CollectBistDataFromPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ 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;
+ PEI_CPU_DATA *CpuData;
+
+ SecPlatformInformation2 = NULL;
+ SecPlatformInformation = NULL;
+ NumberOfData = 0;
+ CpuInstance = NULL;
+
+ //
+ // Get BIST information from Sec Platform Information2 Ppi firstly
+ //
+ Status = GetBistInfoFromPpi (
+ PeiServices,
+ &gEfiSecPlatformInformation2PpiGuid,
+ &SecInformationDescriptor,
+ (VOID *) &SecPlatformInformation2
+ );
+ 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
+ );
+ 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 < PeiCpuMpData->CpuCount; ProcessorNumber ++) {
+ CpuData = &PeiCpuMpData->CpuData[ProcessorNumber];
+ for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
+ ASSERT (CpuInstance != NULL);
+ if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) {
+ //
+ // Update processor's BIST data if it is already stored before
+ //
+ CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
+ }
+ }
+ if (CpuData->Health.Uint32 == 0) {
+ CpuData->CpuHealthy = TRUE;
+ } else {
+ CpuData->CpuHealthy = FALSE;
+ //
+ // 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",
+ PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
+ PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32
+ ));
+ }
+
+ if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) {
+ //
+ // Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion
+ //
+ Status = PeiServicesReInstallPpi (
+ SecInformationDescriptor,
+ &mPeiSecPlatformInformation2Ppi
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // Install SecPlatformInformation2 PPI to include new BIST inforamtion
+ //
+ Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
+ ASSERT_EFI_ERROR(Status);
+ }
+}
diff --git a/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.c
new file mode 100644
index 0000000000..4a453c6570
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -0,0 +1,884 @@
+/** @file
+ CPU PEI Module installs CPU Multiple Processor PPI.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 "CpuMpPei.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ CpuMpEndOfPeiCallback
+};
+
+/**
+ 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 PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+SortApicId (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ UINTN Index1;
+ UINTN Index2;
+ UINTN Index3;
+ UINT32 ApicId;
+ PEI_CPU_DATA CpuData;
+ UINT32 ApCount;
+
+ ApCount = PeiCpuMpData->CpuCount - 1;
+
+ if (ApCount != 0) {
+ for (Index1 = 0; Index1 < ApCount; Index1++) {
+ Index3 = Index1;
+ //
+ // Sort key is the hardware default APIC ID
+ //
+ ApicId = PeiCpuMpData->CpuData[Index1].ApicId;
+ for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) {
+ if (ApicId > PeiCpuMpData->CpuData[Index2].ApicId) {
+ Index3 = Index2;
+ ApicId = PeiCpuMpData->CpuData[Index2].ApicId;
+ }
+ }
+ if (Index3 != Index1) {
+ CopyMem (&CpuData, &PeiCpuMpData->CpuData[Index3], sizeof (PEI_CPU_DATA));
+ CopyMem (
+ &PeiCpuMpData->CpuData[Index3],
+ &PeiCpuMpData->CpuData[Index1],
+ sizeof (PEI_CPU_DATA)
+ );
+ CopyMem (&PeiCpuMpData->CpuData[Index1], &CpuData, sizeof (PEI_CPU_DATA));
+ }
+ }
+
+ //
+ // Get the processor number for the BSP
+ //
+ ApicId = GetInitialApicId ();
+ for (Index1 = 0; Index1 < PeiCpuMpData->CpuCount; Index1++) {
+ if (PeiCpuMpData->CpuData[Index1].ApicId == ApicId) {
+ PeiCpuMpData->BspNumber = (UINT32) Index1;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ Enable x2APIC mode on APs.
+
+ @param Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+ApFuncEnableX2Apic (
+ IN OUT VOID *Buffer
+ )
+{
+ SetApicMode (LOCAL_APIC_MODE_X2APIC);
+}
+
+/**
+ Get AP loop mode.
+
+ @param MonitorFilterSize Returns the largest monitor-line size in bytes.
+
+ @return The AP loop mode.
+**/
+UINT8
+GetApLoopMode (
+ OUT UINT16 *MonitorFilterSize
+ )
+{
+ UINT8 ApLoopMode;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+
+ ASSERT (MonitorFilterSize != NULL);
+
+ ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+ ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);
+ if (ApLoopMode == ApInMwaitLoop) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL);
+ if ((RegEcx & BIT3) == 0) {
+ //
+ // If processor does not support MONITOR/MWAIT feature
+ // by CPUID.[EAX=01H]:ECX.BIT3, force AP in Hlt-loop mode
+ //
+ ApLoopMode = ApInHltLoop;
+ }
+ }
+
+ if (ApLoopMode == ApInHltLoop) {
+ *MonitorFilterSize = 0;
+ } else if (ApLoopMode == ApInRunLoop) {
+ *MonitorFilterSize = sizeof (UINT32);
+ } else if (ApLoopMode == ApInMwaitLoop) {
+ //
+ // 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, &RegEbx, NULL, &RegEdx);
+ *MonitorFilterSize = RegEbx & 0xFFFF;
+ }
+
+ return ApLoopMode;
+}
+
+/**
+ Get CPU MP Data pointer from the Guided HOB.
+
+ @return Pointer to Pointer to PEI CPU MP Data
+**/
+PEI_CPU_MP_DATA *
+GetMpHobData (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ PEI_CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = NULL;
+ GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (GuidHob != NULL) {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ CpuMpData = (PEI_CPU_MP_DATA *)(*(UINTN *)DataInHob);
+ }
+ ASSERT (CpuMpData != NULL);
+ return CpuMpData;
+}
+
+/**
+ Save the volatile registers required to be restored following INIT IPI.
+
+ @param VolatileRegisters Returns buffer saved the volatile resisters
+**/
+VOID
+SaveVolatileRegisters (
+ OUT CPU_VOLATILE_REGISTERS *VolatileRegisters
+ )
+{
+ UINT32 RegEdx;
+
+ VolatileRegisters->Cr0 = AsmReadCr0 ();
+ VolatileRegisters->Cr3 = AsmReadCr3 ();
+ VolatileRegisters->Cr4 = AsmReadCr4 ();
+
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT2) != 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 ();
+ }
+}
+
+/**
+ Restore the volatile registers following INIT IPI.
+
+ @param VolatileRegisters Pointer to volatile resisters
+ @param IsRestoreDr TRUE: Restore DRx if supported
+ FALSE: Do not restore DRx
+**/
+VOID
+RestoreVolatileRegisters (
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
+ IN BOOLEAN IsRestoreDr
+ )
+{
+ UINT32 RegEdx;
+
+ AsmWriteCr0 (VolatileRegisters->Cr0);
+ AsmWriteCr3 (VolatileRegisters->Cr3);
+ AsmWriteCr4 (VolatileRegisters->Cr4);
+
+ if (IsRestoreDr) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT2) != 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);
+ }
+ }
+}
+
+/**
+ This function will be called from AP reset code if BSP uses WakeUpAP.
+
+ @param ExchangeInfo Pointer to the MP exchange info buffer
+ @param NumApsExecuting Number of current executing AP
+**/
+VOID
+EFIAPI
+ApCFunction (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN UINTN NumApsExecuting
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN ProcessorNumber;
+ EFI_AP_PROCEDURE Procedure;
+ UINTN BistData;
+ volatile UINT32 *ApStartupSignalBuffer;
+
+ PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
+ while (TRUE) {
+ if (PeiCpuMpData->InitFlag) {
+ ProcessorNumber = NumApsExecuting;
+ //
+ // Sync BSP's Control registers to APs
+ //
+ RestoreVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters, FALSE);
+ //
+ // This is first time AP wakeup, get BIST information from AP stack
+ //
+ BistData = *(UINTN *) (PeiCpuMpData->Buffer + ProcessorNumber * PeiCpuMpData->CpuApStackSize - sizeof (UINTN));
+ PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 = (UINT32) BistData;
+ PeiCpuMpData->CpuData[ProcessorNumber].ApicId = GetInitialApicId ();
+ if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId >= 0xFF) {
+ //
+ // Set x2APIC mode if there are any logical processor reporting
+ // an APIC ID of 255 or greater.
+ //
+ AcquireSpinLock(&PeiCpuMpData->MpLock);
+ PeiCpuMpData->X2ApicEnable = TRUE;
+ ReleaseSpinLock(&PeiCpuMpData->MpLock);
+ }
+ //
+ // Sync BSP's Mtrr table to all wakeup APs and load microcode on APs.
+ //
+ MtrrSetAllMtrrs (&PeiCpuMpData->MtrrTable);
+ MicrocodeDetect (PeiCpuMpData);
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
+ } else {
+ //
+ // Execute AP function if AP is not disabled
+ //
+ GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
+ if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Restore AP's volatile registers saved
+ //
+ RestoreVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
+ }
+
+ if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) &&
+ (PeiCpuMpData->ApFunction != 0)) {
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateBusy;
+ Procedure = (EFI_AP_PROCEDURE)(UINTN)PeiCpuMpData->ApFunction;
+ //
+ // Invoke AP function here
+ //
+ Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument);
+ //
+ // Re-get the processor number due to BSP/AP maybe exchange in AP function
+ //
+ GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
+ }
+ }
+
+ //
+ // AP finished executing C code
+ //
+ InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount);
+
+ //
+ // Place AP is specified loop mode
+ //
+ if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Save AP volatile registers
+ //
+ SaveVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
+ //
+ // Place AP in Hlt-loop
+ //
+ while (TRUE) {
+ DisableInterrupts ();
+ CpuSleep ();
+ CpuPause ();
+ }
+ }
+ ApStartupSignalBuffer = PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal;
+ while (TRUE) {
+ DisableInterrupts ();
+ if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
+ //
+ // Place AP in Mwait-loop
+ //
+ AsmMonitor ((UINTN)ApStartupSignalBuffer, 0, 0);
+ if (*ApStartupSignalBuffer != WAKEUP_AP_SIGNAL) {
+ //
+ // If AP start-up signal is not set, place AP into
+ // the maximum C-state
+ //
+ AsmMwait (PeiCpuMpData->ApTargetCState << 4, 0);
+ }
+ } else if (PeiCpuMpData->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) {
+ //
+ // Clear AP start-up signal when AP waken up
+ //
+ InterlockedCompareExchange32 (
+ (UINT32 *)ApStartupSignalBuffer,
+ WAKEUP_AP_SIGNAL,
+ 0
+ );
+ break;
+ }
+ }
+ }
+}
+
+/**
+ Write AP start-up signal to wakeup AP.
+
+ @param ApStartupSignalBuffer Pointer to AP wakeup signal
+**/
+VOID
+WriteStartupSignal (
+ IN volatile UINT32 *ApStartupSignalBuffer
+ )
+{
+ *ApStartupSignalBuffer = WAKEUP_AP_SIGNAL;
+ //
+ // 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 be called by BSP to wakeup AP.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param Broadcast TRUE: Send broadcast IPI to all APs
+ FALSE: Send IPI to AP by ApicId
+ @param ProcessorNumber The handle number of specified processor
+ @param Procedure The function to be invoked by AP
+ @param ProcedureArgument The argument to be passed into AP function
+**/
+VOID
+WakeUpAP (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData,
+ IN BOOLEAN Broadcast,
+ IN UINTN ProcessorNumber,
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL
+ IN VOID *ProcedureArgument OPTIONAL
+ )
+{
+ volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINTN Index;
+
+ PeiCpuMpData->ApFunction = (UINTN) Procedure;
+ PeiCpuMpData->ApFunctionArgument = (UINTN) ProcedureArgument;
+ PeiCpuMpData->FinishedCount = 0;
+
+ ExchangeInfo = PeiCpuMpData->MpCpuExchangeInfo;
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->StackStart = PeiCpuMpData->Buffer;
+ ExchangeInfo->StackSize = PeiCpuMpData->CpuApStackSize;
+ ExchangeInfo->BufferStart = PeiCpuMpData->WakeupBuffer;
+ ExchangeInfo->ModeOffset = PeiCpuMpData->AddressMap.ModeEntryOffset;
+ ExchangeInfo->Cr3 = AsmReadCr3 ();
+ ExchangeInfo->CodeSegment = AsmReadCs ();
+ ExchangeInfo->DataSegment = AsmReadDs ();
+ ExchangeInfo->CFunction = (UINTN) ApCFunction;
+ ExchangeInfo->NumApsExecuting = 0;
+ ExchangeInfo->PeiCpuMpData = PeiCpuMpData;
+
+ //
+ // Get the BSP's data of GDT and IDT
+ //
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile);
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);
+
+ if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
+ //
+ // Get AP target C-state each time when waking up AP,
+ // for it maybe updated by platform again
+ //
+ PeiCpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate);
+ }
+
+ //
+ // Wakeup APs per AP loop state
+ //
+ if (PeiCpuMpData->ApLoopMode == ApInHltLoop || PeiCpuMpData->InitFlag) {
+ if (Broadcast) {
+ SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+ } else {
+ SendInitSipiSipi (
+ PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
+ (UINT32) ExchangeInfo->BufferStart
+ );
+ }
+ } else if ((PeiCpuMpData->ApLoopMode == ApInMwaitLoop) ||
+ (PeiCpuMpData->ApLoopMode == ApInRunLoop)) {
+ if (Broadcast) {
+ for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) {
+ if (Index != PeiCpuMpData->BspNumber) {
+ WriteStartupSignal (PeiCpuMpData->CpuData[Index].StartupApSignal);
+ }
+ }
+ } else {
+ WriteStartupSignal (PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal);
+ }
+ } else {
+ ASSERT (FALSE);
+ }
+ return ;
+}
+
+/**
+ Get available system memory below 1MB by specified size.
+
+ @param 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;
+ UINTN WakeupBufferStart;
+ UINTN WakeupBufferEnd;
+
+ //
+ // 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 = (UINTN) (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength);
+ if (WakeupBufferEnd > BASE_1MB) {
+ //
+ // Wakeup buffer should be under 1MB
+ //
+ WakeupBufferEnd = BASE_1MB;
+ }
+ //
+ // Wakeup buffer should be aligned on 4KB
+ //
+ WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1);
+ if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {
+ continue;
+ }
+ //
+ // Create a memory allocation HOB.
+ //
+ BuildMemoryAllocationHob (
+ WakeupBufferStart,
+ WakeupBufferSize,
+ EfiBootServicesData
+ );
+ return WakeupBufferStart;
+ }
+ }
+ //
+ // Find the next HOB
+ //
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return (UINTN) -1;
+}
+
+/**
+ Get available system memory below 1MB by specified size.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+BackupAndPrepareWakeupBuffer(
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ CopyMem (
+ (VOID *) PeiCpuMpData->BackupBuffer,
+ (VOID *) PeiCpuMpData->WakeupBuffer,
+ PeiCpuMpData->BackupBufferSize
+ );
+ CopyMem (
+ (VOID *) PeiCpuMpData->WakeupBuffer,
+ (VOID *) PeiCpuMpData->AddressMap.RendezvousFunnelAddress,
+ PeiCpuMpData->AddressMap.RendezvousFunnelSize
+ );
+}
+
+/**
+ Restore wakeup buffer data.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+RestoreWakeupBuffer(
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ CopyMem ((VOID *) PeiCpuMpData->WakeupBuffer, (VOID *) PeiCpuMpData->BackupBuffer, PeiCpuMpData->BackupBufferSize);
+}
+
+/**
+ This function will get CPU count in the system.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+
+ @return AP processor count
+**/
+UINT32
+CountProcessorNumber (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ //
+ // Load Microcode on BSP
+ //
+ MicrocodeDetect (PeiCpuMpData);
+ //
+ // Store BSP's MTRR setting
+ //
+ MtrrGetAllMtrrs (&PeiCpuMpData->MtrrTable);
+
+ //
+ // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
+ //
+ if (PcdGet32 (PcdCpuMaxLogicalProcessorNumber) > 1) {
+ //
+ // Send 1st broadcast IPI to APs to wakeup APs
+ //
+ PeiCpuMpData->InitFlag = TRUE;
+ PeiCpuMpData->X2ApicEnable = FALSE;
+ WakeUpAP (PeiCpuMpData, TRUE, 0, NULL, NULL);
+ //
+ // Wait for AP task to complete and then exit.
+ //
+ MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+ PeiCpuMpData->InitFlag = FALSE;
+ PeiCpuMpData->CpuCount += (UINT32)PeiCpuMpData->MpCpuExchangeInfo->NumApsExecuting;
+ ASSERT (PeiCpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ //
+ // Wait for all APs finished the initialization
+ //
+ while (PeiCpuMpData->FinishedCount < (PeiCpuMpData->CpuCount - 1)) {
+ CpuPause ();
+ }
+
+ if (PeiCpuMpData->X2ApicEnable) {
+ DEBUG ((EFI_D_INFO, "Force x2APIC mode!\n"));
+ //
+ // Wakeup all APs to enable x2APIC mode
+ //
+ WakeUpAP (PeiCpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL);
+ //
+ // Wait for all known APs finished
+ //
+ while (PeiCpuMpData->FinishedCount < (PeiCpuMpData->CpuCount - 1)) {
+ CpuPause ();
+ }
+ //
+ // Enable x2APIC on BSP
+ //
+ SetApicMode (LOCAL_APIC_MODE_X2APIC);
+ }
+ DEBUG ((EFI_D_INFO, "APIC MODE is %d\n", GetApicMode ()));
+ //
+ // Sort BSP/Aps by CPU APIC ID in ascending order
+ //
+ SortApicId (PeiCpuMpData);
+ }
+
+ DEBUG ((EFI_D_INFO, "CpuMpPei: Find %d processors in system.\n", PeiCpuMpData->CpuCount));
+ return PeiCpuMpData->CpuCount;
+}
+
+/**
+ Prepare for AP wakeup buffer and copy AP reset code into it.
+
+ Get wakeup buffer below 1MB. Allocate memory for CPU MP Data and APs Stack.
+
+ @return Pointer to PEI CPU MP Data
+**/
+PEI_CPU_MP_DATA *
+PrepareAPStartupVector (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 MaxCpuCount;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ EFI_PHYSICAL_ADDRESS Buffer;
+ UINTN BufferSize;
+ UINTN WakeupBuffer;
+ UINTN WakeupBufferSize;
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINT8 ApLoopMode;
+ UINT16 MonitorFilterSize;
+ UINT8 *MonitorBuffer;
+ UINTN Index;
+
+ AsmGetAddressMap (&AddressMap);
+ WakeupBufferSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ WakeupBuffer = GetWakeupBuffer ((WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1));
+ ASSERT (WakeupBuffer != (UINTN) -1);
+ DEBUG ((EFI_D_INFO, "CpuMpPei: WakeupBuffer = 0x%x\n", WakeupBuffer));
+
+ //
+ // Allocate Pages for APs stack, CPU MP Data, backup buffer for wakeup buffer,
+ // and monitor buffer if required.
+ //
+ MaxCpuCount = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
+ BufferSize = PcdGet32 (PcdCpuApStackSize) * MaxCpuCount + sizeof (PEI_CPU_MP_DATA)
+ + WakeupBufferSize + sizeof (PEI_CPU_DATA) * MaxCpuCount;
+ ApLoopMode = GetApLoopMode (&MonitorFilterSize);
+ BufferSize += MonitorFilterSize * MaxCpuCount;
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (BufferSize),
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ PeiCpuMpData = (PEI_CPU_MP_DATA *) (UINTN) (Buffer + PcdGet32 (PcdCpuApStackSize) * MaxCpuCount);
+ PeiCpuMpData->Buffer = (UINTN) Buffer;
+ PeiCpuMpData->CpuApStackSize = PcdGet32 (PcdCpuApStackSize);
+ PeiCpuMpData->WakeupBuffer = WakeupBuffer;
+ PeiCpuMpData->BackupBuffer = (UINTN)PeiCpuMpData + sizeof (PEI_CPU_MP_DATA);
+ PeiCpuMpData->BackupBufferSize = WakeupBufferSize;
+ PeiCpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeupBuffer + AddressMap.RendezvousFunnelSize);
+
+ PeiCpuMpData->CpuCount = 1;
+ PeiCpuMpData->BspNumber = 0;
+ PeiCpuMpData->CpuData = (PEI_CPU_DATA *) (PeiCpuMpData->BackupBuffer +
+ PeiCpuMpData->BackupBufferSize);
+ PeiCpuMpData->CpuData[0].ApicId = GetInitialApicId ();
+ PeiCpuMpData->CpuData[0].Health.Uint32 = 0;
+ PeiCpuMpData->EndOfPeiFlag = FALSE;
+ InitializeSpinLock(&PeiCpuMpData->MpLock);
+ SaveVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters);
+ CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));
+ //
+ // Initialize AP loop mode
+ //
+ PeiCpuMpData->ApLoopMode = ApLoopMode;
+ DEBUG ((EFI_D_INFO, "AP Loop Mode is %d\n", PeiCpuMpData->ApLoopMode));
+ MonitorBuffer = (UINT8 *)(PeiCpuMpData->CpuData + MaxCpuCount);
+ if (PeiCpuMpData->ApLoopMode != ApInHltLoop) {
+ //
+ // Set up APs wakeup signal buffer
+ //
+ for (Index = 0; Index < MaxCpuCount; Index++) {
+ PeiCpuMpData->CpuData[Index].StartupApSignal =
+ (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);
+ }
+ }
+ //
+ // Backup original data and copy AP reset code in it
+ //
+ BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+
+ return PeiCpuMpData;
+}
+
+/**
+ Notify function on End Of Pei PPI.
+
+ On S3 boot, this function will restore wakeup buffer data.
+ On normal boot, this function will flag wakeup buffer to be un-used type.
+
+ @param PeiServices The pointer to the PEI Services Table.
+ @param NotifyDescriptor Address of the notification descriptor data structure.
+ @param Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS When everything is OK.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
+
+ DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invoked\n"));
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ PeiCpuMpData = GetMpHobData ();
+ ASSERT (PeiCpuMpData != NULL);
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ //
+ // 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;
+ if(MemoryHob->AllocDescriptor.MemoryBaseAddress == PeiCpuMpData->WakeupBuffer) {
+ //
+ // Flag this HOB type to un-used
+ //
+ GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
+ break;
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ } else {
+ RestoreWakeupBuffer (PeiCpuMpData);
+ PeiCpuMpData->EndOfPeiFlag = TRUE;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ 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;
+ }
+ Status = InitializeCpuExceptionHandlers (VectorInfo);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Get wakeup buffer and copy AP reset code in it
+ //
+ PeiCpuMpData = PrepareAPStartupVector ();
+ //
+ // Count processor number and collect processor information
+ //
+ CountProcessorNumber (PeiCpuMpData);
+ //
+ // Build location of PEI CPU MP DATA buffer in HOB
+ //
+ BuildGuidDataHob (
+ &gEfiCallerIdGuid,
+ (VOID *)&PeiCpuMpData,
+ sizeof(UINT64)
+ );
+ //
+ // Update and publish CPU BIST information
+ //
+ CollectBistDataFromPpi (PeiServices, PeiCpuMpData);
+ //
+ // register an event for EndOfPei
+ //
+ Status = PeiServicesNotifyPpi (&mNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Install CPU MP PPI
+ //
+ Status = PeiServicesInstallPpi(&mPeiCpuMpPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.h
new file mode 100644
index 0000000000..b2e578b96a
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -0,0 +1,315 @@
+/** @file
+ Definitions to install Multiple Processor PPI.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_MP_PEI_H_
+#define _CPU_MP_PEI_H_
+
+#include <PiPei.h>
+
+#include <Ppi/MpServices.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/VectorHandoffInfo.h>
+
+#include <Register/Cpuid.h>
+#include <Register/LocalApic.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/CpuLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+
+#include "Microcode.h"
+
+//
+// AP state
+//
+typedef enum {
+ CpuStateIdle,
+ CpuStateBusy,
+ CpuStateDisabled
+} CPU_STATE;
+
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
+
+typedef enum {
+ ApInHltLoop = 1,
+ ApInMwaitLoop = 2,
+ ApInRunLoop = 3
+} AP_LOOP_MODE;
+
+//
+// AP reset code information
+//
+typedef struct {
+ UINT8 *RendezvousFunnelAddress;
+ UINTN ModeEntryOffset;
+ UINTN RendezvousFunnelSize;
+} MP_ASSEMBLY_ADDRESS_MAP;
+
+//
+// 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;
+
+typedef struct _PEI_CPU_MP_DATA PEI_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 NumApsExecuting;
+ UINTN CodeSegment;
+ UINTN DataSegment;
+ UINTN Cr3;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+} MP_CPU_EXCHANGE_INFO;
+
+#pragma pack()
+
+typedef struct {
+ UINTN Cr0;
+ UINTN Cr3;
+ UINTN Cr4;
+ UINTN Dr0;
+ UINTN Dr1;
+ UINTN Dr2;
+ UINTN Dr3;
+ UINTN Dr6;
+ UINTN Dr7;
+} CPU_VOLATILE_REGISTERS;
+
+typedef struct {
+ volatile UINT32 *StartupApSignal;
+ UINT32 ApicId;
+ EFI_HEALTH_FLAGS Health;
+ CPU_STATE State;
+ BOOLEAN CpuHealthy;
+ CPU_VOLATILE_REGISTERS VolatileRegisters;
+} PEI_CPU_DATA;
+
+//
+// PEI CPU MP Data save in memory
+//
+struct _PEI_CPU_MP_DATA {
+ SPIN_LOCK MpLock;
+ UINT32 CpuCount;
+ UINT32 BspNumber;
+ UINTN Buffer;
+ UINTN CpuApStackSize;
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINTN WakeupBuffer;
+ UINTN BackupBuffer;
+ UINTN BackupBufferSize;
+ UINTN ApFunction;
+ UINTN ApFunctionArgument;
+ volatile UINT32 FinishedCount;
+ BOOLEAN EndOfPeiFlag;
+ BOOLEAN InitFlag;
+ BOOLEAN X2ApicEnable;
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;
+ CPU_EXCHANGE_ROLE_INFO APInfo;
+ MTRR_SETTINGS MtrrTable;
+ UINT8 ApLoopMode;
+ UINT8 ApTargetCState;
+ PEI_CPU_DATA *CpuData;
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
+};
+extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
+
+
+/**
+ 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 AddressMap Output buffer for address map information.
+**/
+VOID
+EFIAPI
+AsmGetAddressMap (
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
+ );
+
+/**
+ Assembly code to load GDT table and update segment accordingly.
+
+ @param Gdtr Pointer to GDT descriptor
+**/
+VOID
+EFIAPI
+AsmInitializeGdt (
+ IN IA32_DESCRIPTOR *Gdtr
+ );
+
+/**
+ Get available system memory below 1MB by specified size.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+BackupAndPrepareWakeupBuffer(
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ );
+
+/**
+ Restore wakeup buffer data.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+RestoreWakeupBuffer(
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ );
+
+/**
+ Notify function on End Of Pei PPI.
+
+ On S3 boot, this function will restore wakeup buffer data.
+ On normal boot, this function will flag wakeup buffer to be un-used type.
+
+ @param PeiServices The pointer to the PEI Services Table.
+ @param NotifyDescriptor Address of the notification descriptor data structure.
+ @param Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS When everything is OK.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ This function will be called by BSP to wakeup AP.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param Broadcast TRUE: Send broadcast IPI to all APs
+ FALSE: Send IPI to AP by ApicId
+ @param ProcessorNumber The handle number of specified processor
+ @param Procedure The function to be invoked by AP
+ @param ProcedureArgument The argument to be passed into AP function
+**/
+VOID
+WakeUpAP (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData,
+ IN BOOLEAN Broadcast,
+ IN UINTN ProcessorNumber,
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL
+ IN VOID *ProcedureArgument OPTIONAL
+ );
+
+/**
+ Get CPU MP Data pointer from the Guided HOB.
+
+ @return Pointer to Pointer to PEI CPU MP Data
+**/
+PEI_CPU_MP_DATA *
+GetMpHobData (
+ VOID
+ );
+
+/**
+ Find the current Processor number by APIC ID.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param 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 PEI_CPU_MP_DATA *PeiCpuMpData,
+ 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
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+
+**/
+VOID
+CollectBistDataFromPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ );
+
+/**
+ 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
+ );
+
+/**
+ Detect whether specified processor can find matching microcode patch and load it.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+MicrocodeDetect (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
new file mode 100644
index 0000000000..445caf98f2
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -0,0 +1,96 @@
+## @file
+# CPU driver installs CPU PI Multi-processor PPI.
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+ Microcode.h
+ Microcode.c
+ PeiMpServices.h
+ PeiMpServices.c
+
+[Sources.IA32]
+ Ia32/MpEqu.inc
+ Ia32/MpFuncs.asm | MSFT
+ Ia32/MpFuncs.asm | INTEL
+ Ia32/MpFuncs.nasm | GCC
+
+[Sources.X64]
+ X64/MpEqu.inc
+ X64/MpFuncs.asm | MSFT
+ X64/MpFuncs.asm | INTEL
+ X64/MpFuncs.nasm | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ LocalApicLib
+ MtrrLib
+ PcdLib
+ PeimEntryPoint
+ PeiServicesLib
+ ReportStatusCodeLib
+ SynchronizationLib
+ TimerLib
+ UefiCpuLib
+ CpuLib
+ CpuExceptionHandlerLib
+
+[Ppis]
+ gEfiPeiMpServicesPpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## NOTIFY
+ gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
+ ## SOMETIMES_CONSUMES
+ ## SOMETIMES_PRODUCES
+ gEfiSecPlatformInformation2PpiGuid
+ gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuMpPeiExtra.uni
+
diff --git a/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.uni b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.uni
new file mode 100644
index 0000000000..d458d0d624
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuMpPei.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni b/Core/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni
new file mode 100644
index 0000000000..cf832fb80b
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/CpuMpPeiExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// CpuMpPei Localized Strings and Content
+//
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"CPU Multi-processor PEIM Driver"
+
+
diff --git a/Core/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
new file mode 100644
index 0000000000..773eab3a4d
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; 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
+NumApsExecutingLoction equ LockLocation + 24h
+CodeSegmentLocation equ LockLocation + 28h
+DataSegmentLocation equ LockLocation + 2Ch
+
diff --git a/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
new file mode 100644
index 0000000000..27e16c66f4
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
@@ -0,0 +1,250 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; MpFuncs32.asm
+;
+; Abstract:
+;
+; This is the assembly code for MP support
+;
+;-------------------------------------------------------------------------------
+
+.686p
+.model flat
+
+include MpEqu.inc
+InitializeFloatingPointUnits PROTO C
+
+.code
+
+;-------------------------------------------------------------------------------------
+;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 PROC PUBLIC
+RendezvousFunnelProcStart::
+; At this point CS = 0x(vv00) and ip= 0x0.
+; Save BIST information to ebp firstly
+ db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
+
+ db 8ch,0c8h ; mov ax, cs
+ db 8eh,0d8h ; mov ds, ax
+ db 8eh,0c0h ; mov es, ax
+ db 8eh,0d0h ; mov ss, ax
+ db 33h,0c0h ; xor ax, ax
+ db 8eh,0e0h ; mov fs, ax
+ db 8eh,0e8h ; mov gs, ax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]
+
+ db 0BEh ; opcode of mov si, mem16
+ dw ModeOffsetLocation ; mov si, ModeOffsetLocation
+ db 66h, 8Bh, 04h ; mov eax, [si]
+ db 0BEh ; opcode of mov si, mem16
+ dw CodeSegmentLocation ; mov si, CodeSegmentLocation
+ db 66h, 8Bh, 14h ; mov edx, [si]
+ db 89h, 0C7h ; mov di, ax
+ db 83h, 0EFh, 02h ; sub di, 02h
+ db 89h, 15h ; mov [di], dx
+ db 83h, 0EFh, 04h ; sub di, 04h
+ db 66h, 01h, 0D8h ; add eax, ebx
+ db 66h, 89h, 05h ; mov [di], eax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw DataSegmentLocation ; mov si, DataSegmentLocation
+ db 66h, 8Bh, 14h ; mov edx, [si]
+
+ db 0BEh ; opcode of mov si, mem16
+ dw GdtrLocation ; mov si, GdtrLocation
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh
+ dw IdtrLocation ; mov si, IdtrLocation
+ db 66h ; db 66h
+ db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 33h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
+ db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+ db 66h, 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 0h ; 16-bit selector
+
+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, LockLocation
+ mov eax, NotVacantFlag
+
+TestLock:
+ xchg dword ptr [edi], eax
+ cmp eax, NotVacantFlag
+ jz TestLock
+
+ mov edi, esi
+ add edi, NumApsExecutingLoction
+ inc dword ptr [edi]
+ mov ebx, dword ptr [edi]
+
+ProgramStack:
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov eax, dword ptr [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add eax, dword ptr [edi]
+ mov esp, eax
+ mov dword ptr [edi], eax
+
+Releaselock:
+ mov eax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg dword ptr [edi], eax
+
+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, InitializeFloatingPointUnits
+ call eax ; Call assembly function to initialize FPU per UEFI spec
+
+ push ebx ; Push NumApsExecuting
+ mov eax, esi
+ add eax, LockLocation
+ push eax ; push address of exchange info data buffer
+
+ mov edi, esi
+ add edi, ApProcedureLocation
+ mov eax, dword ptr [edi]
+
+ call eax ; invoke C function
+
+ jmp $ ; never reach here
+
+RendezvousFunnelProc ENDP
+RendezvousFunnelProcEnd::
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+AsmGetAddressMap PROC near C PUBLIC
+ pushad
+ mov ebp,esp
+
+ mov ebx, dword ptr [ebp+24h]
+ mov dword ptr [ebx], RendezvousFunnelProcStart
+ mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
+ mov dword ptr [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+
+ popad
+ ret
+AsmGetAddressMap ENDP
+
+PAUSE32 MACRO
+ DB 0F3h
+ DB 090h
+ ENDM
+
+;-------------------------------------------------------------------------------------
+;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);
+;-------------------------------------------------------------------------------------
+AsmExchangeRole PROC near C PUBLIC
+ ; 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, dword ptr [ebp+24h]
+
+ ; edi contains OthersInfo pointer
+ mov edi, dword ptr [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 fword ptr [esi+8]
+ sidt fword ptr [esi+14]
+
+ ; Store the its StackPointer
+ mov dword ptr [esi+4],esp
+
+ ; update its switch state to STORED
+ mov byte ptr [esi], CPU_SWITCH_STATE_STORED
+
+WaitForOtherStored:
+ ; wait until the other CPU finish storing its state
+ cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
+ jz OtherStored
+ PAUSE32
+ jmp WaitForOtherStored
+
+OtherStored:
+ ; Since another CPU already stored its state, load them
+ ; load GDTR value
+ lgdt fword ptr [edi+8]
+
+ ; load IDTR value
+ lidt fword ptr [edi+14]
+
+ ; load its future StackPointer
+ mov esp, dword ptr [edi+4]
+
+ ; update the other CPU's switch state to LOADED
+ mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
+
+WaitForOtherLoaded:
+ ; wait until the other CPU finish loading new state,
+ ; otherwise the data in stack may corrupt
+ cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
+ jz OtherLoaded
+ PAUSE32
+ 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
+AsmExchangeRole ENDP
+
+END
diff --git a/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
new file mode 100644
index 0000000000..0852a5bc84
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
@@ -0,0 +1,229 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; 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, ModeOffsetLocation
+ mov eax, [si]
+ mov si, CodeSegmentLocation
+ mov edx, [si]
+ mov di, ax
+ sub di, 02h
+ mov [di], dx
+ sub di, 04h
+ add eax, ebx
+ mov [di],eax
+
+ mov si, DataSegmentLocation
+ mov edx, [si]
+
+ 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, 000000003h ;Set PE bit (bit #0) & MP
+ mov cr0, eax
+
+ jmp 0:strict dword 0 ; far jump to protected mode
+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, LockLocation
+ mov eax, NotVacantFlag
+
+TestLock:
+ xchg [edi], eax
+ cmp eax, NotVacantFlag
+ jz TestLock
+
+ mov edi, esi
+ add edi, NumApsExecutingLoction
+ inc dword [edi]
+ mov ebx, [edi]
+
+ProgramStack:
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov eax, [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add eax, [edi]
+ mov esp, eax
+ mov [edi], eax
+
+Releaselock:
+ mov eax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg [edi], eax
+
+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 NumApsExecuting
+ 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:
+
+;-------------------------------------------------------------------------------------
+; 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
+
+ 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/Core/UefiCpuPkg/CpuMpPei/Microcode.c b/Core/UefiCpuPkg/CpuMpPei/Microcode.c
new file mode 100644
index 0000000000..f91f658d0a
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/Microcode.c
@@ -0,0 +1,213 @@
+/** @file
+ Implementation of loading microcode on processors.
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 "CpuMpPei.h"
+
+/**
+ Get microcode update signature of currently loaded microcode update.
+
+ @return Microcode signature.
+
+**/
+UINT32
+GetCurrentMicrocodeSignature (
+ VOID
+ )
+{
+ UINT64 Signature;
+
+ AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+ Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
+ return (UINT32) RShiftU64 (Signature, 32);
+}
+
+/**
+ Detect whether specified processor can find matching microcode patch and load it.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+MicrocodeDetect (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ UINT64 MicrocodePatchAddress;
+ UINT64 MicrocodePatchRegionSize;
+ UINT32 ExtendedTableLength;
+ UINT32 ExtendedTableCount;
+ EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
+ EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+ EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
+ UINTN MicrocodeEnd;
+ UINTN Index;
+ UINT8 PlatformId;
+ UINT32 RegEax;
+ UINT32 CurrentRevision;
+ UINT32 LatestRevision;
+ UINTN TotalSize;
+ UINT32 CheckSum32;
+ BOOLEAN CorrectMicrocode;
+ MICROCODE_INFO MicrocodeInfo;
+
+ ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
+ MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
+ MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
+ if (MicrocodePatchRegionSize == 0) {
+ //
+ // There is no microcode patches
+ //
+ return;
+ }
+
+ CurrentRevision = GetCurrentMicrocodeSignature ();
+ if (CurrentRevision != 0) {
+ //
+ // Skip loading microcode if it has been loaded successfully
+ //
+ 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, &RegEax, NULL, NULL, NULL);
+
+ //
+ // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
+ //
+ PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
+
+ LatestRevision = 0;
+ MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
+ MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) 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->HeaderVersion == 0x1) {
+ //
+ // It is the microcode header. It is not the padding data between microcode patches
+ // becasue the padding data should not include 0x00000001 and it should be the repeated
+ // byte format (like 0xXYXYXYXY....).
+ //
+ if (MicrocodeEntryPoint->ProcessorId == RegEax &&
+ MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
+ (MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
+ ) {
+ if (MicrocodeEntryPoint->DataSize == 0) {
+ CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
+ } else {
+ CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
+ }
+ if (CheckSum32 == 0) {
+ CorrectMicrocode = TRUE;
+ }
+ } else if ((MicrocodeEntryPoint->DataSize != 0) &&
+ (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
+ ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ if (ExtendedTableLength != 0) {
+ //
+ // Extended Table exist, check if the CPU in support list
+ //
+ ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ //
+ // Calculate Extended Checksum
+ //
+ if ((ExtendedTableLength % 4) == 0) {
+ CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
+ if (CheckSum32 == 0) {
+ //
+ // Checksum correct
+ //
+ ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
+ ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
+ for (Index = 0; Index < ExtendedTableCount; Index ++) {
+ CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
+ if (CheckSum32 == 0) {
+ //
+ // Verify Header
+ //
+ if ((ExtendedTable->ProcessorSignature == RegEax) &&
+ (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 = (EFI_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;
+ MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
+ MicrocodeInfo.MicrocodeSize = TotalSize;
+ MicrocodeInfo.ProcessorId = RegEax;
+ }
+
+ MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
+ } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
+
+ 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.
+ //
+ AsmWriteMsr64 (
+ EFI_MSR_IA32_BIOS_UPDT_TRIG,
+ (UINT64) (UINTN) MicrocodeInfo.MicrocodeData
+ );
+ //
+ // Get and check new microcode signature
+ //
+ CurrentRevision = GetCurrentMicrocodeSignature ();
+ if (CurrentRevision != LatestRevision) {
+ AcquireSpinLock(&PeiCpuMpData->MpLock);
+ DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \
+ loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));
+ ReleaseSpinLock(&PeiCpuMpData->MpLock);
+ }
+ }
+}
diff --git a/Core/UefiCpuPkg/CpuMpPei/Microcode.h b/Core/UefiCpuPkg/CpuMpPei/Microcode.h
new file mode 100644
index 0000000000..965604522a
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/Microcode.h
@@ -0,0 +1,58 @@
+/** @file
+ Definitions for loading microcode on processors.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_MICROCODE_H_
+#define _CPU_MICROCODE_H_
+
+#define EFI_MSR_IA32_PLATFORM_ID 0x17
+#define EFI_MSR_IA32_BIOS_UPDT_TRIG 0x79
+#define EFI_MSR_IA32_BIOS_SIGN_ID 0x8b
+
+#define MAX_MICROCODE_DESCRIPTOR_LENGTH 100
+
+typedef struct {
+ VOID *MicrocodeData;
+ UINTN MicrocodeSize;
+ UINT32 ProcessorId;
+} MICROCODE_INFO;
+
+//
+// Definition for IA32 microcode format
+//
+typedef struct {
+ UINT32 HeaderVersion;
+ UINT32 UpdateRevision;
+ UINT32 Date;
+ UINT32 ProcessorId;
+ UINT32 Checksum;
+ UINT32 LoaderRevision;
+ UINT32 ProcessorFlags;
+ UINT32 DataSize;
+ UINT32 TotalSize;
+ UINT8 Reserved[12];
+} EFI_CPU_MICROCODE_HEADER;
+
+typedef struct {
+ UINT32 ExtendedSignatureCount;
+ UINT32 ExtendedTableChecksum;
+ UINT8 Reserved[12];
+} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+typedef struct {
+ UINT32 ProcessorSignature;
+ UINT32 ProcessorFlag;
+ UINT32 ProcessorChecksum;
+} EFI_CPU_MICROCODE_EXTENDED_TABLE;
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.c
new file mode 100644
index 0000000000..e784377d67
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -0,0 +1,956 @@
+/** @file
+ Implementation of Multiple Processor PPI services.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 "PeiMpServices.h"
+
+//
+// CPU MP PPI to be installed
+//
+EFI_PEI_MP_SERVICES_PPI mMpServicesPpi = {
+ PeiGetNumberOfProcessors,
+ PeiGetProcessorInfo,
+ PeiStartupAllAPs,
+ PeiStartupThisAP,
+ PeiSwitchBSP,
+ PeiEnableDisableAP,
+ PeiWhoAmI,
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMpServicesPpiGuid,
+ &mMpServicesPpi
+};
+
+/**
+ Get CPU Package/Core/Thread location information.
+
+ @param InitialApicId CPU APIC ID
+ @param Location Pointer to CPU location information
+**/
+VOID
+ExtractProcessorLocation (
+ IN UINT32 InitialApicId,
+ OUT EFI_CPU_PHYSICAL_LOCATION *Location
+ )
+{
+ BOOLEAN TopologyLeafSupported;
+ UINTN ThreadBits;
+ UINTN CoreBits;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT32 MaxCpuIdIndex;
+ UINT32 SubIndex;
+ UINTN LevelType;
+ UINT32 MaxLogicProcessorsPerPackage;
+ UINT32 MaxCoresPerPackage;
+
+ //
+ // Check if the processor is capable of supporting more than one logical processor.
+ //
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT28) == 0) {
+ Location->Thread = 0;
+ Location->Core = 0;
+ Location->Package = 0;
+ return;
+ }
+
+ ThreadBits = 0;
+ CoreBits = 0;
+
+ //
+ // Assume three-level mapping of APIC ID: Package:Core:SMT.
+ //
+
+ TopologyLeafSupported = FALSE;
+ //
+ // Get the max index of basic CPUID
+ //
+ AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
+
+ //
+ // If the extended topology enumeration leaf is available, it
+ // is the preferred mechanism for enumerating topology.
+ //
+ if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
+ AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, 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 (RegEbx != 0) {
+ TopologyLeafSupported = TRUE;
+
+ //
+ // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
+ // the SMT sub-field of x2APIC ID.
+ //
+ LevelType = (RegEcx >> 8) & 0xff;
+ ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
+ ThreadBits = RegEax & 0x1f;
+
+ //
+ // 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, &RegEax, NULL, &RegEcx, NULL);
+ LevelType = (RegEcx >> 8) & 0xff;
+ if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
+ CoreBits = (RegEax & 0x1f) - ThreadBits;
+ break;
+ }
+ SubIndex++;
+ } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
+ }
+ }
+
+ if (!TopologyLeafSupported) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
+ MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff;
+ if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
+ AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL);
+ MaxCoresPerPackage = (RegEax >> 26) + 1;
+ } else {
+ //
+ // Must be a single-core processor.
+ //
+ MaxCoresPerPackage = 1;
+ }
+
+ ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
+ CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
+ }
+
+ Location->Thread = InitialApicId & ~((-1) << ThreadBits);
+ Location->Core = (InitialApicId >> ThreadBits) & ~((-1) << CoreBits);
+ Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
+}
+
+/**
+ Find the current Processor number by APIC ID.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param 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 PEI_CPU_MP_DATA *PeiCpuMpData,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ UINTN TotalProcessorNumber;
+ UINTN Index;
+
+ TotalProcessorNumber = PeiCpuMpData->CpuCount;
+ for (Index = 0; Index < TotalProcessorNumber; Index ++) {
+ if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Worker function for SwitchBSP().
+
+ Worker function for SwitchBSP(), assigned to the AP which is intended to become BSP.
+
+ @param Buffer Pointer to CPU MP Data
+**/
+VOID
+EFIAPI
+FutureBSPProc (
+ IN VOID *Buffer
+ )
+{
+ PEI_CPU_MP_DATA *DataInHob;
+
+ DataInHob = (PEI_CPU_MP_DATA *) Buffer;
+ AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
+}
+
+/**
+ 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+ UINTN ProcessorNumber;
+ UINTN EnabledProcessorNumber;
+ UINTN Index;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ProcessorNumber = PeiCpuMpData->CpuCount;
+ EnabledProcessorNumber = 0;
+ for (Index = 0; Index < ProcessorNumber; Index++) {
+ if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
+ EnabledProcessorNumber ++;
+ }
+ }
+
+ *NumberOfProcessors = ProcessorNumber;
+ *NumberOfEnabledProcessors = EnabledProcessorNumber;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorInfoBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ ProcessorInfoBuffer->ProcessorId = (UINT64) PeiCpuMpData->CpuData[ProcessorNumber].ApicId;
+ ProcessorInfoBuffer->StatusFlag = 0;
+ if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId == GetInitialApicId()) {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
+ }
+ if (PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy) {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT;
+ }
+ if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
+ ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT;
+ } else {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;
+ }
+
+ //
+ // Get processor location information
+ //
+ ExtractProcessorLocation (PeiCpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN ProcessorNumber;
+ UINTN Index;
+ UINTN CallerNumber;
+ BOOLEAN HasEnabledAp;
+ BOOLEAN HasEnabledIdleAp;
+ volatile UINT32 *FinishedCount;
+ EFI_STATUS Status;
+ UINTN WaitCountIndex;
+ UINTN WaitCountNumber;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ProcessorNumber = PeiCpuMpData->CpuCount;
+
+ HasEnabledAp = FALSE;
+ HasEnabledIdleAp = FALSE;
+ for (Index = 0; Index < ProcessorNumber; Index ++) {
+ if (Index == CallerNumber) {
+ //
+ // Skip BSP
+ //
+ continue;
+ }
+ if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
+ HasEnabledAp = TRUE;
+ if (PeiCpuMpData->CpuData[Index].State != CpuStateBusy) {
+ HasEnabledIdleAp = TRUE;
+ }
+ }
+ }
+ if (!HasEnabledAp) {
+ //
+ // If no enabled AP exists, return EFI_NOT_STARTED.
+ //
+ return EFI_NOT_STARTED;
+ }
+ if (!HasEnabledIdleAp) {
+ //
+ // If any enabled APs are busy, return EFI_NOT_READY.
+ //
+ return EFI_NOT_READY;
+ }
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Backup original data and copy AP reset vector in it
+ //
+ BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+ }
+
+ WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1;
+ WaitCountIndex = 0;
+ FinishedCount = &PeiCpuMpData->FinishedCount;
+ if (!SingleThread) {
+ WakeUpAP (PeiCpuMpData, TRUE, 0, Procedure, ProcedureArgument);
+ //
+ // Wait to finish
+ //
+ if (TimeoutInMicroSeconds == 0) {
+ while (*FinishedCount < ProcessorNumber - 1) {
+ CpuPause ();
+ }
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_TIMEOUT;
+ for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
+ MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
+ if (*FinishedCount >= ProcessorNumber - 1) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+ } else {
+ Status = EFI_SUCCESS;
+ for (Index = 0; Index < ProcessorNumber; Index++) {
+ if (Index == CallerNumber) {
+ continue;
+ }
+ WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument);
+ //
+ // Wait to finish
+ //
+ if (TimeoutInMicroSeconds == 0) {
+ while (*FinishedCount < 1) {
+ CpuPause ();
+ }
+ } else {
+ for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
+ MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
+ if (*FinishedCount >= 1) {
+ break;
+ }
+ }
+ if (WaitCountIndex == WaitCountNumber) {
+ Status = EFI_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Restore original data
+ //
+ RestoreWakeupBuffer(PeiCpuMpData);
+ }
+
+ return Status;
+}
+
+/**
+ 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+ volatile UINT32 *FinishedCount;
+ EFI_STATUS Status;
+ UINTN WaitCountIndex;
+ UINTN WaitCountNumber;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (ProcessorNumber == PeiCpuMpData->BspNumber || Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether specified AP is disabled
+ //
+ if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Backup original data and copy AP reset vector in it
+ //
+ BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+ }
+
+ WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;
+ WaitCountIndex = 0;
+ FinishedCount = &PeiCpuMpData->FinishedCount;
+
+ WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);
+
+ //
+ // Wait to finish
+ //
+ if (TimeoutInMicroseconds == 0) {
+ while (*FinishedCount < 1) {
+ CpuPause() ;
+ }
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_TIMEOUT;
+ for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
+ MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
+ if (*FinishedCount >= 1) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Backup original data and copy AP reset vector in it
+ //
+ RestoreWakeupBuffer(PeiCpuMpData);
+ }
+
+ 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.
+
+ 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_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
+ AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+**/
+EFI_STATUS
+EFIAPI
+PeiSwitchBSP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+ MSR_IA32_APIC_BASE ApicBaseMsr;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_SUCCESS;
+ }
+
+ if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether specified AP is disabled
+ //
+ if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether ProcessorNumber specifies the current BSP
+ //
+ if (ProcessorNumber == PeiCpuMpData->BspNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether specified AP is busy
+ //
+ if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateBusy) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Clear the BSP bit of MSR_IA32_APIC_BASE
+ //
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Bits.Bsp = 0;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+
+ PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
+ PeiCpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE;
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Backup original data and copy AP reset vector in it
+ //
+ BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+ }
+
+ //
+ // Need to wakeUp AP (future BSP).
+ //
+ WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData);
+
+ AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);
+
+ if (PeiCpuMpData->EndOfPeiFlag) {
+ //
+ // Backup original data and copy AP reset vector in it
+ //
+ RestoreWakeupBuffer(PeiCpuMpData);
+ }
+
+ //
+ // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
+ //
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Bits.Bsp = 1;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ //
+ // Set old BSP enable state
+ //
+ if (!EnableOldBSP) {
+ PeiCpuMpData->CpuData[PeiCpuMpData->BspNumber].State = CpuStateDisabled;
+ }
+ //
+ // Save new BSP number
+ //
+ PeiCpuMpData->BspNumber = (UINT32) ProcessorNumber;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ PeiWhoAmI (PeiServices, This, &CallerNumber);
+ if (CallerNumber != PeiCpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber == PeiCpuMpData->BspNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!EnableAP) {
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateDisabled;
+ } else {
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
+ }
+
+ if (HealthFlag != NULL) {
+ PeiCpuMpData->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.
+
+ 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
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+
+ PeiCpuMpData = GetMpHobData ();
+ if (PeiCpuMpData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (ProcessorNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return GetProcessorNumber (PeiCpuMpData, ProcessorNumber);
+}
+
diff --git a/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.h b/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.h
new file mode 100644
index 0000000000..57f7691161
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/PeiMpServices.h
@@ -0,0 +1,377 @@
+/** @file
+ Functions prototype of Multiple Processor PPI services.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 _PEI_MP_SERVICES_H_
+#define _PEI_MP_SERVICES_H_
+
+#include "CpuMpPei.h"
+
+//
+// The MP data for switch BSP
+//
+#define CPU_SWITCH_STATE_IDLE 0
+#define CPU_SWITCH_STATE_STORED 1
+#define CPU_SWITCH_STATE_LOADED 2
+
+#define CPU_CHECK_AP_INTERVAL 0x100 // 100 microseconds
+
+/**
+ 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 MyInfo Pointer to buffer holding the exchanging information for the executing processor.
+ @param 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
+ );
+
+/**
+ 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_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
+ AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+**/
+EFI_STATUS
+EFIAPI
+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
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc b/Core/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
new file mode 100644
index 0000000000..00f57ce549
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; 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
+NumApsExecutingLoction equ LockLocation + 44h
+CodeSegmentLocation equ LockLocation + 4Ch
+DataSegmentLocation equ LockLocation + 54h
+Cr3Location equ LockLocation + 5Ch
+
+;-------------------------------------------------------------------------------
diff --git a/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm b/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
new file mode 100644
index 0000000000..4adfff3c1c
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
@@ -0,0 +1,290 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; MpFuncs32.asm
+;
+; Abstract:
+;
+; This is the assembly code for MP support
+;
+;-------------------------------------------------------------------------------
+
+include MpEqu.inc
+extern InitializeFloatingPointUnits:PROC
+
+.code
+;-------------------------------------------------------------------------------------
+;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 PROC PUBLIC
+RendezvousFunnelProcStart::
+; At this point CS = 0x(vv00) and ip= 0x0.
+; Save BIST information to ebp firstly
+ db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
+
+ db 8ch,0c8h ; mov ax, cs
+ db 8eh,0d8h ; mov ds, ax
+ db 8eh,0c0h ; mov es, ax
+ db 8eh,0d0h ; mov ss, ax
+ db 33h,0c0h ; xor ax, ax
+ db 8eh,0e0h ; mov fs, ax
+ db 8eh,0e8h ; mov gs, ax
+
+ db 0BEh ; opcode of mov si, mem16
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]
+
+ db 0BFh ; opcode of mov di, mem16
+ dw ModeOffsetLocation ; mov di, ModeOffsetLocation
+ db 66h, 8Bh, 05h ; mov eax, [di]
+ db 0BFh ; opcode of mov di, mem16
+ dw CodeSegmentLocation ; mov di, CodeSegmentLocation
+ db 66h, 8Bh, 15h ; mov edx, [di]
+ db 89h, 0C7h ; mov di, ax
+ db 83h, 0EFh, 02h ; sub di, 02h
+ db 89h, 15h ; mov [di], dx ; Patch long mode CS
+ db 83h, 0EFh, 04h ; sub di, 04h
+ db 66h, 01h, 0D8h ; add eax, ebx
+ db 66h, 89h, 05h ; mov [di], eax ; Patch address
+
+ db 0BEh ; opcode of mov si, mem16
+ dw GdtrLocation ; mov si, GdtrLocation
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh
+ dw IdtrLocation ; mov si, IdtrLocation
+ db 66h ; db 66h
+ db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 0BFh ; opcode of mov di, mem16
+ dw DataSegmentLocation ; mov di, DataSegmentLocation
+ db 66h, 8Bh, 3Dh ; mov edi, [di] ; Save long mode DS in edi
+
+ db 0BEh
+ dw Cr3Location ; mov si, Cr3Location
+ db 66h, 8Bh, 0Ch ; mov ecx, dword ptr [si] ; ECX is keeping the value of CR3
+
+ db 31h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax ; Clear data segment
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
+ db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ; Set PE bit (bit #0) & MP
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+ db 0Fh, 20h, 0E0h ; mov eax, cr4
+ db 66h, 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
+ db 0Fh, 22h, 0E0h ; mov cr4, eax
+
+ db 0Fh, 22h, 0D9h ; mov cr3, ecx
+
+ db 66h, 0B9h
+ dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
+ db 0Fh, 32h ; rdmsr ; Read EFER.
+ db 66h, 0Fh, 0BAh, 0E8h, 08h; bts eax, 8 ; Set LME=1.
+ db 0Fh, 30h ; wrmsr ; Write EFER.
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
+ db 66h, 0Fh, 0BAh, 0E8h, 1Fh; bts eax, 31 ; Set PG=1.
+ db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
+
+LONG_JUMP:
+ db 66h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 0h ; 16-bit selector
+
+LongModeStart::
+ mov eax, edi
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ mov esi, ebx
+ mov edi, esi
+ add edi, LockLocation
+ mov rax, NotVacantFlag
+
+TestLock:
+ xchg qword ptr [edi], rax
+ cmp rax, NotVacantFlag
+ jz TestLock
+
+ mov edi, esi
+ add edi, NumApsExecutingLoction
+ inc dword ptr [edi]
+ mov ebx, dword ptr [edi]
+
+ProgramStack:
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov rax, qword ptr [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add rax, qword ptr [edi]
+ mov rsp, rax
+ mov qword ptr [edi], rax
+
+Releaselock:
+ mov rax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg qword ptr [edi], rax
+
+CProcedureInvoke:
+ push rbp ; push BIST data
+ xor rbp, rbp ; clear ebp for call stack trace
+ push rbp
+ mov rbp, rsp
+
+ mov rax, InitializeFloatingPointUnits
+ sub rsp, 20h
+ call rax ; Call assembly function to initialize FPU per UEFI spec
+ add rsp, 20h
+
+ mov edx, ebx ; edx is NumApsExecuting
+ mov ecx, esi
+ add ecx, LockLocation ; rcx is address of exchange info data buffer
+
+ mov edi, esi
+ add edi, ApProcedureLocation
+ mov rax, qword ptr [edi]
+
+ sub rsp, 20h
+ call rax ; invoke C function
+ add rsp, 20h
+ jmp $
+
+RendezvousFunnelProc ENDP
+RendezvousFunnelProcEnd::
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+AsmGetAddressMap PROC
+ mov rax, offset RendezvousFunnelProcStart
+ mov qword ptr [rcx], rax
+ mov qword ptr [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
+ mov qword ptr [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+ ret
+AsmGetAddressMap ENDP
+
+;-------------------------------------------------------------------------------------
+;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);
+;-------------------------------------------------------------------------------------
+AsmExchangeRole PROC
+ ; 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 fword ptr [rsi + 16]
+ sidt fword ptr [rsi + 26]
+
+ ; Store the its StackPointer
+ mov qword ptr [rsi + 8], rsp
+
+ ; update its switch state to STORED
+ mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
+
+WaitForOtherStored:
+ ; wait until the other CPU finish storing its state
+ cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
+ jz OtherStored
+ pause
+ jmp WaitForOtherStored
+
+OtherStored:
+ ; Since another CPU already stored its state, load them
+ ; load GDTR value
+ lgdt fword ptr [rdi + 16]
+
+ ; load IDTR value
+ lidt fword ptr [rdi + 26]
+
+ ; load its future StackPointer
+ mov rsp, qword ptr [rdi + 8]
+
+ ; update the other CPU's switch state to LOADED
+ mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
+
+WaitForOtherLoaded:
+ ; wait until the other CPU finish loading new state,
+ ; otherwise the data in stack may corrupt
+ cmp byte ptr [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
+AsmExchangeRole ENDP
+
+END
diff --git a/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm b/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
new file mode 100644
index 0000000000..f19c75f913
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
@@ -0,0 +1,281 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; 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 di, ModeOffsetLocation
+ mov eax, [di]
+ mov di, CodeSegmentLocation
+ mov edx, [di]
+ mov di, ax
+ sub di, 02h
+ mov [di],dx ; Patch long mode CS
+ sub di, 04h
+ add eax, ebx
+ mov [di],eax ; Patch address
+
+ mov si, GdtrLocation
+o32 lgdt [cs:si]
+
+ mov si, IdtrLocation
+o32 lidt [cs:si]
+
+
+ mov di, DataSegmentLocation
+ mov edi, [di] ; Save long mode DS in edi
+
+ mov si, Cr3Location ; Save CR3 in ecx
+ mov ecx, [si]
+
+ xor ax, ax
+ mov ds, ax ; Clear data segment
+
+ mov eax, cr0 ; Get control register 0
+ or eax, 000000003h ; Set PE bit (bit #0) & MP
+ mov cr0, eax
+
+ mov eax, cr4
+ bts eax, 5
+ mov cr4, eax
+
+ mov cr3, ecx ; Load CR3
+
+ mov ecx, 0c0000080h ; 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
+
+ jmp 0:strict dword 0 ; far jump to long mode
+BITS 64
+LongModeStart:
+ mov eax, edi
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ mov esi, ebx
+ mov edi, esi
+ add edi, LockLocation
+ mov rax, NotVacantFlag
+
+TestLock:
+ xchg qword [edi], rax
+ cmp rax, NotVacantFlag
+ jz TestLock
+
+ mov edi, esi
+ add edi, NumApsExecutingLoction
+ inc dword [edi]
+ mov ebx, [edi]
+
+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 rax, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg qword [edi], rax
+
+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, ASM_PFX(InitializeFloatingPointUnits)
+ sub rsp, 20h
+ call rax ; Call assembly function to initialize FPU per UEFI spec
+ add rsp, 20h
+
+ mov edx, ebx ; edx is NumApsExecuting
+ 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 $
+
+RendezvousFunnelProcEnd:
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmGetAddressMap)
+ASM_PFX(AsmGetAddressMap):
+ mov rax, ASM_PFX(RendezvousFunnelProc)
+ mov qword [rcx], rax
+ mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
+ mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+ 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.
+
+ 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/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
new file mode 100644
index 0000000000..9fb47dc528
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
@@ -0,0 +1,271 @@
+/** @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 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiDxe.h>
+
+#include <AcpiCpuData.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MtrrLib.h>
+
+#include <Protocol/MpService.h>
+#include <Guid/EventGroup.h>
+
+//
+// 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 below 4G memory address.
+
+ This function allocates EfiACPIMemoryNVS below 4G memory address.
+
+ @param[in] Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+VOID *
+AllocateAcpiNvsMemoryBelow4G (
+ IN UINTN Size
+ )
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Address = BASE_4GB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (Size),
+ &Address
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Buffer = (VOID *)(UINTN)Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+/**
+ Callback function executed when the EndOfDxe event group is signaled.
+
+ We delay 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
+SaveMtrrsOnEndOfDxe (
+ IN EFI_EVENT Event,
+ OUT VOID *Context
+ )
+{
+ DEBUG ((EFI_D_VERBOSE, "%a\n", __FUNCTION__));
+ MtrrGetAllMtrrs (Context);
+
+ //
+ // 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 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;
+
+ //
+ // Allocate ACPI NVS memory below 4G memory for use on ACPI S3 resume.
+ //
+ AcpiCpuDataEx = AllocateAcpiNvsMemoryBelow4G (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);
+
+ //
+ // Allocate a 4KB reserved page below 1MB
+ //
+ AcpiCpuData->StartupVector = BASE_1MB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ 1,
+ &AcpiCpuData->StartupVector
+ );
+ 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
+ //
+ Stack = AllocateAcpiNvsMemoryBelow4G (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 in ACPI NVS and copy current GDT and IDT contents
+ //
+ GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;
+ IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;
+ Gdt = AllocateAcpiNvsMemoryBelow4G (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;
+
+ //
+ // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
+ //
+ TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
+ RegisterTable = (CPU_REGISTER_TABLE *)AllocateAcpiNvsMemoryBelow4G (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 = NULL;
+
+ RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
+ RegisterTable[NumberOfCpus + Index].TableLength = 0;
+ RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;
+ RegisterTable[NumberOfCpus + Index].RegisterTableEntry = NULL;
+ }
+ 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 saves MTRRs for ACPI_CPU_DATA
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SaveMtrrsOnEndOfDxe,
+ &AcpiCpuDataEx->MtrrTable,
+ &gEfiEndOfDxeEventGroupGuid,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
new file mode 100644
index 0000000000..857e12b802
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
@@ -0,0 +1,68 @@
+## @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-2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015, Red Hat, Inc.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ MtrrLib
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
+
+[Protocols]
+ gEfiMpServiceProtocolGuid ## CONSUMES
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## PRODUCES
+
+[Depex]
+ gEfiMpServiceProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuS3DataDxeExtra.uni
diff --git a/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni
new file mode 100644
index 0000000000..4a0218f180
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.uni
@@ -0,0 +1,40 @@
+// /** @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.<BR>
+//
+// Copyright (c) 2015, Red Hat, Inc.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni
new file mode 100644
index 0000000000..050f25f843
--- /dev/null
+++ b/Core/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxeExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// CpuS3DataDxe Localized Strings and Content
+//
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// Copyright (c) 2015, Red Hat, Inc.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME #language en-US "CpuS3DataDxe module"
+
+
diff --git a/Core/UefiCpuPkg/Include/AcpiCpuData.h b/Core/UefiCpuPkg/Include/AcpiCpuData.h
new file mode 100644
index 0000000000..12e9692c5c
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/AcpiCpuData.h
@@ -0,0 +1,160 @@
+/** @file
+Definitions for CPU S3 data.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _ACPI_CPU_DATA_H_
+#define _ACPI_CPU_DATA_H_
+
+//
+// Register types in register table
+//
+typedef enum {
+ Msr,
+ ControlRegister,
+ MemoryMapped,
+ CacheControl
+} REGISTER_TYPE;
+
+//
+// Element of register table entry
+//
+typedef struct {
+ REGISTER_TYPE RegisterType;
+ UINT32 Index;
+ UINT8 ValidBitStart;
+ UINT8 ValidBitLength;
+ UINT64 Value;
+} 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;
+ //
+ // Buffer of CPU_REGISTER_TABLE_ENTRY structures. This buffer must be
+ // allocated below 4GB from memory of type EfiACPIMemoryNVS.
+ //
+ CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
+} CPU_REGISTER_TABLE;
+
+//
+// Data structure that is required for ACPI S3 resume. This structure must be
+// allocated below 4GB from memory of type EfiACPIMemoryNVS. 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. This structure must
+ // be allocated below 4GB from memory of type EfiACPIMemoryNVS. The
+ // IA32_DESCRIPTOR structure provides the base address and length of a GDT
+ // The buffer for GDT must also be allocated below 4GB from memory of type
+ // EfiACPIMemoryNVS. 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. This structure must
+ // be allocated below 4GB from memory of type EfiACPIMemoryNVS. The
+ // IA32_DESCRIPTOR structure provides the base address and length of an IDT.
+ // The buffer for IDT must also be allocated below 4GB from memory of type
+ // EfiACPIMemoryNVS. 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 below 4GB 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. This structure must be allocated below 4GB
+ // from memory of type EfiACPIMemoryNVS.
+ //
+ EFI_PHYSICAL_ADDRESS MtrrTable;
+ //
+ // Physical address of an array of CPU_REGISTER_TABLE structures, with
+ // NumberOfCpus entries. This array must be allocated below 4GB from memory
+ // of type EfiACPIMemoryNVS. 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. This array must be allocated below 4GB from memory
+ // of type EfiACPIMemoryNVS. 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. This buffer must be allocated below 4GB
+ // from memory of type EfiACPIMemoryNVS. 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;
+} ACPI_CPU_DATA;
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/CpuHotPlugData.h b/Core/UefiCpuPkg/Include/CpuHotPlugData.h
new file mode 100644
index 0000000000..2a0d9fabd5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/CpuHotPlugData.h
@@ -0,0 +1,33 @@
+/** @file
+Definition for a structure sharing information for CPU hot plug.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_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/Core/UefiCpuPkg/Include/Library/LocalApicLib.h b/Core/UefiCpuPkg/Include/Library/LocalApicLib.h
new file mode 100644
index 0000000000..cd4e613ef5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/LocalApicLib.h
@@ -0,0 +1,415 @@
+/** @file
+ Public include file for Local APIC library.
+
+ Local APIC library assumes local APIC is enabled. It does not
+ handles cases where local APIC is disabled.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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_LIB_H__
+#define __LOCAL_APIC_LIB_H__
+
+#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.
+
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ Get the local APIC ID of the executing processor.
+
+ @return 32-bit local APIC ID of the executing processor.
+**/
+UINT32
+EFIAPI
+GetApicId (
+ VOID
+ );
+
+/**
+ Get the value of the local APIC version register.
+
+ @return the value of the local APIC version register.
+**/
+UINT32
+EFIAPI
+GetApicVersion (
+ VOID
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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.
+
+ 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
+ );
+
+/**
+ Disable LINT0 & LINT1 interrupts.
+
+ This function sets the mask flag in the LVT LINT0 & LINT1 registers.
+**/
+VOID
+EFIAPI
+DisableLvtInterrupts (
+ VOID
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ Enable the local APIC timer interrupt.
+**/
+VOID
+EFIAPI
+EnableApicTimerInterrupt (
+ VOID
+ );
+
+/**
+ Disable the local APIC timer interrupt.
+**/
+VOID
+EFIAPI
+DisableApicTimerInterrupt (
+ VOID
+ );
+
+/**
+ 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
+ );
+
+/**
+ Send EOI to the local APIC.
+**/
+VOID
+EFIAPI
+SendApicEoi (
+ VOID
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+#endif
+
diff --git a/Core/UefiCpuPkg/Include/Library/MtrrLib.h b/Core/UefiCpuPkg/Include/Library/MtrrLib.h
new file mode 100644
index 0000000000..36cd2cd6d5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/MtrrLib.h
@@ -0,0 +1,386 @@
+/** @file
+ MTRR setting library
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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
+// Note: It is replaced by PCD PcdCpuNumberOfReservedVariableMtrrs
+//
+#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[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.
+
+**/
+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 fixed 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 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
+ );
+
+/**
+ 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.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttributeInMtrrSettings (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
+ );
+
+#endif // _MTRR_LIB_H_
diff --git a/Core/UefiCpuPkg/Include/Library/PlatformSecLib.h b/Core/UefiCpuPkg/Include/Library/PlatformSecLib.h
new file mode 100644
index 0000000000..0af7781771
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/PlatformSecLib.h
@@ -0,0 +1,70 @@
+/** @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.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 __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/Core/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h b/Core/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h
new file mode 100644
index 0000000000..4478003467
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h
@@ -0,0 +1,401 @@
+/** @file
+Library that provides CPU specific functions to support the PiSmmCpuDxeSmm module.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 __SMM_FEATURES_LIB_H__
+#define __SMM_FEATURES_LIB_H__
+
+#include <Protocol/MpService.h>
+#include <Protocol/SmmCpu.h>
+#include <Register/SmramSaveStateMap.h>
+#include <CpuHotPlugData.h>
+
+///
+/// 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.
+
+ @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
+ );
+
+/**
+ 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_PARAMTER 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_PARAMTER 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/Core/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h b/Core/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h
new file mode 100644
index 0000000000..e40084edf9
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h
@@ -0,0 +1,109 @@
+/** @file
+ Public include file for the SMM CPU Platform Hook Library.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 __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/Core/UefiCpuPkg/Include/Library/UefiCpuLib.h b/Core/UefiCpuPkg/Include/Library/UefiCpuLib.h
new file mode 100644
index 0000000000..561d579968
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Library/UefiCpuLib.h
@@ -0,0 +1,38 @@
+/** @file
+ Public header file for UEFI CPU library class.
+
+ This library class defines some routines that are generic for IA32 family CPU
+ to be UEFI specification compliant.
+
+ Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 __UEFI_CPU_LIB_H__
+#define __UEFI_CPU_LIB_H__
+
+
+
+/**
+ 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).
+
+**/
+VOID
+EFIAPI
+InitializeFloatingPointUnits (
+ VOID
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Protocol/SmmCpuService.h b/Core/UefiCpuPkg/Include/Protocol/SmmCpuService.h
new file mode 100644
index 0000000000..9aced54f4d
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Protocol/SmmCpuService.h
@@ -0,0 +1,209 @@
+/** @file
+SMM CPU Service protocol definition.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _SMM_CPU_SERVICE_PROTOCOL_H_
+#define _SMM_CPU_SERVICE_PROTOCOL_H_
+
+//
+// Share some definitions with MP Services and CPU Arch Protocol
+//
+#include <Protocol/MpService.h>
+#include <Protocol/Cpu.h>
+
+#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/Core/UefiCpuPkg/Include/Register/ArchitecturalMsr.h b/Core/UefiCpuPkg/Include/Register/ArchitecturalMsr.h
new file mode 100644
index 0000000000..a4702edc73
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/ArchitecturalMsr.h
@@ -0,0 +1,5801 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-1.
+
+**/
+
+#ifndef __ARCHITECTURAL_MSR_H__
+#define __ARCHITECTURAL_MSR_H__
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_P5_MC_ADDR);
+ AsmWriteMsr64 (MSR_IA32_P5_MC_ADDR, Msr);
+ @endcode
+**/
+#define MSR_IA32_P5_MC_ADDR 0x00000000
+
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_P5_MC_TYPE);
+ AsmWriteMsr64 (MSR_IA32_P5_MC_TYPE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MONITOR_FILTER_SIZE);
+ AsmWriteMsr64 (MSR_IA32_MONITOR_FILTER_SIZE, Msr);
+ @endcode
+**/
+#define MSR_IA32_MONITOR_FILTER_SIZE 0x00000006
+
+
+/**
+ See Section 17.14, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_TIME_STAMP_COUNTER);
+ AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_APIC_BASE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_FEATURE_CONTROL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
+ AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, Msr.Uint64);
+ @endcode
+**/
+#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:2;
+ ///
+ /// [Bit 18] SGX Global Enable (R/WL): This bit must be set to enable SGX
+ /// leaf functions. This bit is supported only if CPUID.1:ECX.[bit 6] is
+ /// set. 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_TSC_ADJUST);
+ AsmWriteMsr64 (MSR_IA32_TSC_ADJUST, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = 0;
+ AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_BIOS_SIGN_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+ @endcode
+**/
+#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;
+
+
+/**
+ SMM Monitor Configuration (R/W). If CPUID.01H: ECX[5]=1. 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_SMBASE);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_PMC0);
+ AsmWriteMsr64 (MSR_IA32_PMC0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MPERF);
+ AsmWriteMsr64 (MSR_IA32_MPERF, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_APERF);
+ AsmWriteMsr64 (MSR_IA32_APERF, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MTRRCAP_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_SYSENTER_CS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SYSENTER_CS);
+ AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_SYSENTER_ESP);
+ AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_SYSENTER_EIP);
+ AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MCG_CAP_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MCG_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_STATUS);
+ AsmWriteMsr64 (MSR_IA32_MCG_STATUS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MCG_CTL);
+ AsmWriteMsr64 (MSR_IA32_MCG_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERFEVTSEL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_IA32_PERFEVTSEL0, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERF_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERF_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_CTL);
+ AsmWriteMsr64 (MSR_IA32_PERF_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.". Introduced at Display Family / Display Model 0F_0H.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_CLOCK_MODULATION_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_CLOCK_MODULATION);
+ AsmWriteMsr64 (MSR_IA32_CLOCK_MODULATION, Msr.Uint64);
+ @endcode
+**/
+#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.
+ ///
+ UINT32 OnDemandClockModulationDutyCycle:3;
+ ///
+ /// [Bit 4] On-Demand Clock Modulation Enable: Set 1 to enable modulation.
+ ///
+ 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.".
+ Introduced at Display Family / Display Model 0F_0H.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_THERM_INTERRUPT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_THERM_INTERRUPT);
+ AsmWriteMsr64 (MSR_IA32_THERM_INTERRUPT, Msr.Uint64);
+ @endcode
+**/
+#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.
+ ///
+ UINT32 HighTempEnable:1;
+ ///
+ /// [Bit 1] Low-Temperature Interrupt Enable.
+ ///
+ UINT32 LowTempEnable:1;
+ ///
+ /// [Bit 2] PROCHOT# Interrupt Enable.
+ ///
+ UINT32 PROCHOT_Enable:1;
+ ///
+ /// [Bit 3] FORCEPR# Interrupt Enable.
+ ///
+ UINT32 FORCEPR_Enable:1;
+ ///
+ /// [Bit 4] Critical Temperature Interrupt Enable.
+ ///
+ UINT32 CriticalTempEnable:1;
+ UINT32 Reserved1:3;
+ ///
+ /// [Bits 14:8] Threshold #1 Value.
+ ///
+ UINT32 Threshold1:7;
+ ///
+ /// [Bit 15] Threshold #1 Interrupt Enable.
+ ///
+ UINT32 Threshold1Enable:1;
+ ///
+ /// [Bits 22:16] Threshold #2 Value.
+ ///
+ UINT32 Threshold2:7;
+ ///
+ /// [Bit 23] Threshold #2 Interrupt Enable.
+ ///
+ 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". Introduced at Display Family / Display
+ Model 0F_0H.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_THERM_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_THERM_STATUS);
+ @endcode
+**/
+#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):.
+ ///
+ UINT32 ThermalStatus:1;
+ ///
+ /// [Bit 1] Thermal Status Log (R/W):.
+ ///
+ UINT32 ThermalStatusLog:1;
+ ///
+ /// [Bit 2] PROCHOT # or FORCEPR# event (RO).
+ ///
+ UINT32 PROCHOT_FORCEPR_Event:1;
+ ///
+ /// [Bit 3] PROCHOT # or FORCEPR# log (R/WC0).
+ ///
+ UINT32 PROCHOT_FORCEPR_Log:1;
+ ///
+ /// [Bit 4] Critical Temperature Status (RO).
+ ///
+ UINT32 CriticalTempStatus:1;
+ ///
+ /// [Bit 5] Critical Temperature Status log (R/WC0).
+ ///
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MISC_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);
+ AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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. 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] Precise 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 3. BIOS should contain a setup
+ /// question that allows users to specify when the installed OS does not
+ /// support CPUID functions greater than 3. 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 3, the bit is
+ /// supported. Otherwise, the bit is not supported. Writing to this bit
+ /// when the maximum value is greater than 3 may generate a #GP exception.
+ /// Setting this bit may cause unexpected behavior in software that
+ /// depends on the availability of CPUID leaves greater than 3. 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PACKAGE_THERM_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PACKAGE_THERM_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_DEBUGCTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_DEBUGCTL);
+ AsmWriteMsr64 (MSR_IA32_DEBUGCTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_SMRR_PHYSBASE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SMRR_PHYSBASE);
+ AsmWriteMsr64 (MSR_IA32_SMRR_PHYSBASE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_SMRR_PHYSMASK_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SMRR_PHYSMASK);
+ AsmWriteMsr64 (MSR_IA32_SMRR_PHYSMASK, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_PLATFORM_DCA_CAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_CPU_DCA_CAP);
+ AsmWriteMsr64 (MSR_IA32_CPU_DCA_CAP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MTRR_PHYSBASE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0);
+ AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MTRR_PHYSMASK_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0);
+ AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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:8;
+ ///
+ /// [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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX64K_00000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX64K_00000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX16K_80000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX16K_80000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX16K_A0000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX16K_A0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_C0000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_C0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_C8000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_C8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_D0000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_D0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_D8000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_D8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_E0000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_E0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_E8000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_E8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_F0000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_F0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MTRR_FIX4K_F8000);
+ AsmWriteMsr64 (MSR_IA32_MTRR_FIX4K_F8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PAT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PAT);
+ AsmWriteMsr64 (MSR_IA32_PAT, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_MC_CTL2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_MC0_CTL2);
+ AsmWriteMsr64 (MSR_IA32_MC0_CTL2, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR0);
+ AsmWriteMsr64 (MSR_IA32_FIXED_CTR0, Msr);
+ @endcode
+**/
+#define MSR_IA32_FIXED_CTR0 0x00000309
+
+
+/**
+ Fixed-Function Performance Counter 1 0 (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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR1);
+ AsmWriteMsr64 (MSR_IA32_FIXED_CTR1, Msr);
+ @endcode
+**/
+#define MSR_IA32_FIXED_CTR1 0x0000030A
+
+
+/**
+ Fixed-Function Performance Counter 0 0 (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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_FIXED_CTR2);
+ AsmWriteMsr64 (MSR_IA32_FIXED_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERF_CAPABILITIES_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_CAPABILITIES);
+ AsmWriteMsr64 (MSR_IA32_PERF_CAPABILITIES, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERF_GLOBAL_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PERF_GLOBAL_INUSE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_GLOBAL_INUSE);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PEBS_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_IA32_PEBS_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MC0_CTL);
+ AsmWriteMsr64 (MSR_IA32_MC0_CTL, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MC0_STATUS);
+ AsmWriteMsr64 (MSR_IA32_MC0_STATUS, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MC0_ADDR);
+ AsmWriteMsr64 (MSR_IA32_MC0_ADDR, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_MC0_MISC);
+ AsmWriteMsr64 (MSR_IA32_MC0_MISC, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_BASIC);
+ @endcode
+**/
+#define MSR_IA32_VMX_BASIC 0x00000480
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_PINBASED_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_PROCBASED_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_EXIT_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_ENTRY_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_MISC);
+ @endcode
+**/
+#define MSR_IA32_VMX_MISC 0x00000485
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_CR0_FIXED0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_CR0_FIXED1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_CR4_FIXED0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_CR4_FIXED1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_VMCS_ENUM);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_PROCBASED_CTLS2);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_EPT_VPID_CAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_PINBASED_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_PROCBASED_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_EXIT_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_TRUE_ENTRY_CTLS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_VMX_VMFUNC);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_A_PMC0);
+ AsmWriteMsr64 (MSR_IA32_A_PMC0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_SGX_SVN_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_SGX_SVN_STATUS);
+ @endcode
+**/
+#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.12.3, "Interactions with Authenticated
+ /// Code Modules (ACMs)".
+ ///
+ UINT32 Lock:1;
+ UINT32 Reserved1:15;
+ ///
+ /// [Bits 23:16] SGX_SVN_SINIT. See Section 42.12.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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_RTIT_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CTL);
+ AsmWriteMsr64 (MSR_IA32_RTIT_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_RTIT_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_STATUS);
+ AsmWriteMsr64 (MSR_IA32_RTIT_STATUS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_RTIT_ADDR_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_ADDR0_A);
+ AsmWriteMsr64 (MSR_IA32_RTIT_ADDR0_A, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_RTIT_ADDR_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_ADDR0_B);
+ AsmWriteMsr64 (MSR_IA32_RTIT_ADDR0_B, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_DS_AREA);
+ AsmWriteMsr64 (MSR_IA32_DS_AREA, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_TSC_DEADLINE);
+ AsmWriteMsr64 (MSR_IA32_TSC_DEADLINE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PM_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PM_ENABLE);
+ AsmWriteMsr64 (MSR_IA32_PM_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_HWP_CAPABILITIES_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_CAPABILITIES);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_HWP_INTERRUPT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_INTERRUPT);
+ AsmWriteMsr64 (MSR_IA32_HWP_INTERRUPT, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_HWP_REQUEST_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_REQUEST);
+ AsmWriteMsr64 (MSR_IA32_HWP_REQUEST, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_HWP_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_HWP_STATUS);
+ AsmWriteMsr64 (MSR_IA32_HWP_STATUS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_APICID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_VERSION);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_TPR);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_TPR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_PPR);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = 0;
+ AsmWriteMsr64 (MSR_IA32_X2APIC_EOI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LDR);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_SIVR);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_SIVR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ISR0);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_TMR0);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_IRR0);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ESR);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_ESR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_CMCI);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_CMCI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_ICR);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_ICR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_TIMER);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_TIMER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_THERMAL);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_THERMAL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_PMI);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_PMI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_LINT0);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_LINT0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_LINT1);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_LINT1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_LVT_ERROR);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_LVT_ERROR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_INIT_COUNT);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_INIT_COUNT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_CUR_COUNT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_X2APIC_DIV_CONF);
+ AsmWriteMsr64 (MSR_IA32_X2APIC_DIV_CONF, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = 0;
+ AsmWriteMsr64 (MSR_IA32_X2APIC_SELF_IPI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_DEBUG_INTERFACE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_DEBUG_INTERFACE);
+ AsmWriteMsr64 (MSR_IA32_DEBUG_INTERFACE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_QM_EVTSEL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_QM_EVTSEL);
+ AsmWriteMsr64 (MSR_IA32_QM_EVTSEL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_QM_CTR_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_QM_CTR);
+ @endcode
+**/
+#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 ).
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PQR_ASSOC_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PQR_ASSOC);
+ AsmWriteMsr64 (MSR_IA32_PQR_ASSOC, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_BNDCFGS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_BNDCFGS);
+ AsmWriteMsr64 (MSR_IA32_BNDCFGS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_XSS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_XSS);
+ AsmWriteMsr64 (MSR_IA32_XSS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_PM_CTL1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PM_CTL1);
+ AsmWriteMsr64 (MSR_IA32_PM_CTL1, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_THREAD_STALL);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_EFER_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
+ AsmWriteMsr64 (MSR_IA32_EFER, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_STAR);
+ AsmWriteMsr64 (MSR_IA32_STAR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_LSTAR);
+ AsmWriteMsr64 (MSR_IA32_LSTAR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_FMASK);
+ AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_FS_BASE);
+ AsmWriteMsr64 (MSR_IA32_FS_BASE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_GS_BASE);
+ AsmWriteMsr64 (MSR_IA32_GS_BASE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IA32_KERNEL_GS_BASE);
+ AsmWriteMsr64 (MSR_IA32_KERNEL_GS_BASE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IA32_TSC_AUX_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_TSC_AUX);
+ AsmWriteMsr64 (MSR_IA32_TSC_AUX, Msr.Uint64);
+ @endcode
+**/
+#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/Core/UefiCpuPkg/Include/Register/Cpuid.h b/Core/UefiCpuPkg/Include/Register/Cpuid.h
new file mode 100644
index 0000000000..eb24840746
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Cpuid.h
@@ -0,0 +1,3406 @@
+/** @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.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License which accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, 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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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. The Machine Check Architecture,
+ /// which provides a compatible mechanism for error reporting in P6 family,
+ /// Pentium 4, Intel Xeon processors, and future processors, 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.
+
+ <b>Example usage</b>
+ @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
+
+ <b>Cache Descriptor values</b>
+ <table>
+ <tr><th>Value </th><th> Type </th><th> Description </th></tr>
+ <tr><td> 0x00 </td><td> General </td><td> Null descriptor, this byte contains no information</td></tr>
+ <tr><td> 0x01 </td><td> TLB </td><td> Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries</td></tr>
+ <tr><td> 0x02 </td><td> TLB </td><td> Instruction TLB: 4 MByte pages, fully associative, 2 entries</td></tr>
+ <tr><td> 0x03 </td><td> TLB </td><td> Data TLB: 4 KByte pages, 4-way set associative, 64 entries</td></tr>
+ <tr><td> 0x04 </td><td> TLB </td><td> Data TLB: 4 MByte pages, 4-way set associative, 8 entries</td></tr>
+ <tr><td> 0x05 </td><td> TLB </td><td> Data TLB1: 4 MByte pages, 4-way set associative, 32 entries</td></tr>
+ <tr><td> 0x06 </td><td> Cache </td><td> 1st-level instruction cache: 8 KBytes, 4-way set associative,
+ 32 byte line size</td></tr>
+ <tr><td> 0x08 </td><td> Cache </td><td> 1st-level instruction cache: 16 KBytes, 4-way set associative,
+ 32 byte line size</td></tr>
+ <tr><td> 0x09 </td><td> Cache </td><td> 1st-level instruction cache: 32KBytes, 4-way set associative,
+ 64 byte line size</td></tr>
+ <tr><td> 0x0A </td><td> Cache </td><td> 1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x0B </td><td> TLB </td><td> Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries</td></tr>
+ <tr><td> 0x0C </td><td> Cache </td><td> 1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x0D </td><td> Cache </td><td> 1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x0E </td><td> Cache </td><td> 1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x1D </td><td> Cache </td><td> 2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x21 </td><td> Cache </td><td> 2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x22 </td><td> Cache </td><td> 3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x23 </td><td> Cache </td><td> 3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x24 </td><td> Cache </td><td> 2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x25 </td><td> Cache </td><td> 3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x29 </td><td> Cache </td><td> 3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x2C </td><td> Cache </td><td> 1st-level data cache: 32 KBytes, 8-way set associative,
+ 64 byte line size</td></tr>
+ <tr><td> 0x30 </td><td> Cache </td><td> 1st-level instruction cache: 32 KBytes, 8-way set associative,
+ 64 byte line size</td></tr>
+ <tr><td> 0x40 </td><td> Cache </td><td> No 2nd-level cache or, if processor contains a valid 2nd-level cache,
+ no 3rd-level cache</td></tr>
+ <tr><td> 0x41 </td><td> Cache </td><td> 2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x42 </td><td> Cache </td><td> 2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x43 </td><td> Cache </td><td> 2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x44 </td><td> Cache </td><td> 2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x45 </td><td> Cache </td><td> 2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x46 </td><td> Cache </td><td> 3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x47 </td><td> Cache </td><td> 3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x48 </td><td> Cache </td><td> 2nd-level cache: 3MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x49 </td><td> Cache </td><td> 3rd-level cache: 4MB, 16-way set associative, 64-byte line size
+ (Intel Xeon processor MP, Family 0FH, Model 06H)<BR>
+ 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4A </td><td> Cache </td><td> 3rd-level cache: 6MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4B </td><td> Cache </td><td> 3rd-level cache: 8MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4C </td><td> Cache </td><td> 3rd-level cache: 12MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4D </td><td> Cache </td><td> 3rd-level cache: 16MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4E </td><td> Cache </td><td> 2nd-level cache: 6MByte, 24-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x4F </td><td> TLB </td><td> Instruction TLB: 4 KByte pages, 32 entries</td></tr>
+ <tr><td> 0x50 </td><td> TLB </td><td> Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries</td></tr>
+ <tr><td> 0x51 </td><td> TLB </td><td> Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries</td></tr>
+ <tr><td> 0x52 </td><td> TLB </td><td> Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries</td></tr>
+ <tr><td> 0x55 </td><td> TLB </td><td> Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries</td></tr>
+ <tr><td> 0x56 </td><td> TLB </td><td> Data TLB0: 4 MByte pages, 4-way set associative, 16 entries</td></tr>
+ <tr><td> 0x57 </td><td> TLB </td><td> Data TLB0: 4 KByte pages, 4-way associative, 16 entries</td></tr>
+ <tr><td> 0x59 </td><td> TLB </td><td> Data TLB0: 4 KByte pages, fully associative, 16 entries</td></tr>
+ <tr><td> 0x5A </td><td> TLB </td><td> Data TLB0: 2-MByte or 4 MByte pages, 4-way set associative, 32 entries</td></tr>
+ <tr><td> 0x5B </td><td> TLB </td><td> Data TLB: 4 KByte and 4 MByte pages, 64 entries</td></tr>
+ <tr><td> 0x5C </td><td> TLB </td><td> Data TLB: 4 KByte and 4 MByte pages,128 entries</td></tr>
+ <tr><td> 0x5D </td><td> TLB </td><td> Data TLB: 4 KByte and 4 MByte pages,256 entries</td></tr>
+ <tr><td> 0x60 </td><td> Cache </td><td> 1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x61 </td><td> TLB </td><td> Instruction TLB: 4 KByte pages, fully associative, 48 entries</td></tr>
+ <tr><td> 0x63 </td><td> TLB </td><td> Data TLB: 1 GByte pages, 4-way set associative, 4 entries</td></tr>
+ <tr><td> 0x66 </td><td> Cache </td><td> 1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x67 </td><td> Cache </td><td> 1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x68 </td><td> Cache </td><td> 1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x6A </td><td> Cache </td><td> uTLB: 4 KByte pages, 8-way set associative, 64 entries</td></tr>
+ <tr><td> 0x6B </td><td> Cache </td><td> DTLB: 4 KByte pages, 8-way set associative, 256 entries</td></tr>
+ <tr><td> 0x6C </td><td> Cache </td><td> DTLB: 2M/4M pages, 8-way set associative, 128 entries</td></tr>
+ <tr><td> 0x6D </td><td> Cache </td><td> DTLB: 1 GByte pages, fully associative, 16 entries</td></tr>
+ <tr><td> 0x70 </td><td> Cache </td><td> Trace cache: 12 K-uop, 8-way set associative</td></tr>
+ <tr><td> 0x71 </td><td> Cache </td><td> Trace cache: 16 K-uop, 8-way set associative</td></tr>
+ <tr><td> 0x72 </td><td> Cache </td><td> Trace cache: 32 K-uop, 8-way set associative</td></tr>
+ <tr><td> 0x76 </td><td> TLB </td><td> Instruction TLB: 2M/4M pages, fully associative, 8 entries</td></tr>
+ <tr><td> 0x78 </td><td> Cache </td><td> 2nd-level cache: 1 MByte, 4-way set associative, 64byte line size</td></tr>
+ <tr><td> 0x79 </td><td> Cache </td><td> 2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x7A </td><td> Cache </td><td> 2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x7B </td><td> Cache </td><td> 2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x7C </td><td> Cache </td><td> 2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size,
+ 2 lines per sector</td></tr>
+ <tr><td> 0x7D </td><td> Cache </td><td> 2nd-level cache: 2 MByte, 8-way set associative, 64byte line size</td></tr>
+ <tr><td> 0x7F </td><td> Cache </td><td> 2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size</td></tr>
+ <tr><td> 0x80 </td><td> Cache </td><td> 2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size</td></tr>
+ <tr><td> 0x82 </td><td> Cache </td><td> 2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x83 </td><td> Cache </td><td> 2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x84 </td><td> Cache </td><td> 2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x85 </td><td> Cache </td><td> 2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size</td></tr>
+ <tr><td> 0x86 </td><td> Cache </td><td> 2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0x87 </td><td> Cache </td><td> 2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xA0 </td><td> DTLB </td><td> DTLB: 4k pages, fully associative, 32 entries</td></tr>
+ <tr><td> 0xB0 </td><td> TLB </td><td> Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries</td></tr>
+ <tr><td> 0xB1 </td><td> TLB </td><td> Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries</td></tr>
+ <tr><td> 0xB2 </td><td> TLB </td><td> Instruction TLB: 4KByte pages, 4-way set associative, 64 entries</td></tr>
+ <tr><td> 0xB3 </td><td> TLB </td><td> Data TLB: 4 KByte pages, 4-way set associative, 128 entries</td></tr>
+ <tr><td> 0xB4 </td><td> TLB </td><td> Data TLB1: 4 KByte pages, 4-way associative, 256 entries</td></tr>
+ <tr><td> 0xB5 </td><td> TLB </td><td> Instruction TLB: 4KByte pages, 8-way set associative, 64 entries</td></tr>
+ <tr><td> 0xB6 </td><td> TLB </td><td> Instruction TLB: 4KByte pages, 8-way set associative,
+ 128 entries</td></tr>
+ <tr><td> 0xBA </td><td> TLB </td><td> Data TLB1: 4 KByte pages, 4-way associative, 64 entries</td></tr>
+ <tr><td> 0xC0 </td><td> TLB </td><td> Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries</td></tr>
+ <tr><td> 0xC1 </td><td> STLB </td><td> Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative,
+ 1024 entries</td></tr>
+ <tr><td> 0xC2 </td><td> DTLB </td><td> DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries</td></tr>
+ <tr><td> 0xC3 </td><td> STLB </td><td> Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative,
+ 1536 entries. Also 1GBbyte pages, 4-way, 16 entries.</td></tr>
+ <tr><td> 0xCA </td><td> STLB </td><td> Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries</td></tr>
+ <tr><td> 0xD0 </td><td> Cache </td><td> 3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xD1 </td><td> Cache </td><td> 3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xD2 </td><td> Cache </td><td> 3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xD6 </td><td> Cache </td><td> 3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xD7 </td><td> Cache </td><td> 3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xD8 </td><td> Cache </td><td> 3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xDC </td><td> Cache </td><td> 3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xDD </td><td> Cache </td><td> 3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xDE </td><td> Cache </td><td> 3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xE2 </td><td> Cache </td><td> 3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xE3 </td><td> Cache </td><td> 3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xE4 </td><td> Cache </td><td> 3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xEA </td><td> Cache </td><td> 3rd-level cache: 12MByte, 24-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xEB </td><td> Cache </td><td> 3rd-level cache: 18MByte, 24-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xEC </td><td> Cache </td><td> 3rd-level cache: 24MByte, 24-way set associative, 64 byte line size</td></tr>
+ <tr><td> 0xF0 </td><td> Prefetch</td><td> 64-Byte prefetching</td></tr>
+ <tr><td> 0xF1 </td><td> Prefetch</td><td> 128-Byte prefetching</td></tr>
+ <tr><td> 0xFF </td><td> General </td><td> CPUID leaf 2 does not report cache descriptor information,
+ use CPUID leaf 4 to query cache parameters</td></tr>
+ </table>
+**/
+#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.)
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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
+ );
+ SubLeaf++;
+ } while (SubLeaf <= Eax);
+ @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 Platform Quality of Service Monitoring (PQM)
+ /// capability if 1.
+ ///
+ UINT32 PQM: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 Platform Quality of Service Enforcement (PQE)
+ /// capability if 1.
+ ///
+ UINT32 PQE: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;
+ UINT32 Reserved4:1;
+ ///
+ /// [Bit 25] If 1 indicates the processor supports the Intel Processor Trace
+ /// extensions.
+ ///
+ UINT32 IntelProcessorTrace:1;
+ UINT32 Reserved5:6;
+ } 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:2;
+ ///
+ /// [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:27;
+ } 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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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 Platform QoS Monitoring Information
+
+ @param EAX CPUID_PLATFORM_QOS_MONITORING (0x0F)
+ @param ECX CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF (0x00).
+ CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF (0x01).
+
+**/
+#define CPUID_PLATFORM_QOS_MONITORING 0x0F
+
+/**
+ CPUID Platform QoS Monitoring Information Enumeration Sub-leaf
+
+ @param EAX CPUID_PLATFORM_QOS_MONITORING (0x0F)
+ @param ECX CPUID_PLATFORM_QOS_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 QoS Monitoring Information Enumeration described by the
+ type CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX.
+
+ <b>Example usage</b>
+ @code
+ UINT32 Ebx;
+ CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx;
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF,
+ NULL, &Ebx, NULL, &Edx.Uint32
+ );
+ @endcode
+**/
+#define CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF 0x00
+
+/**
+ CPUID Platform QoS Monitoring Information EDX for CPUID leaf
+ #CPUID_PLATFORM_QOS_MONITORING, sub-leaf
+ #CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF.
+**/
+typedef union {
+ ///
+ /// Individual bit fields
+ ///
+ struct {
+ UINT32 Reserved1:1;
+ ///
+ /// [Bit 1] Supports L3 Cache QoS Monitoring if 1.
+ ///
+ UINT32 L3CacheQosEnforcement:1;
+ UINT32 Reserved2:30;
+ } Bits;
+ ///
+ /// All bit fields as a 32-bit value
+ ///
+ UINT32 Uint32;
+} CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX;
+
+/**
+ CPUID Platform QoS Monitoring Information Capability Sub-leaf
+
+ @param EAX CPUID_PLATFORM_QOS_MONITORING (0x0F)
+ @param ECX CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_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 QoS Monitoring Capability information described by the
+ type CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX.
+
+ <b>Example usage</b>
+ @code
+ UINT32 Ebx;
+ UINT32 Ecx;
+ CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX Edx;
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF,
+ NULL, &Ebx, &Ecx, &Edx.Uint32
+ );
+ @endcode
+**/
+#define CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF 0x01
+
+/**
+ CPUID Platform QoS Monitoring Information Capability EDX for CPUID leaf
+ #CPUID_PLATFORM_QOS_MONITORING, sub-leaf
+ #CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF.
+**/
+typedef union {
+ ///
+ /// Individual bit fields
+ ///
+ struct {
+ ///
+ /// [Bit 0] Supports L3 occupancy monitoring if 1.
+ ///
+ UINT32 L3CacheOccupancyMonitoring:1;
+ UINT32 Reserved:31;
+ } Bits;
+ ///
+ /// All bit fields as a 32-bit value
+ ///
+ UINT32 Uint32;
+} CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX;
+
+
+/**
+ CPUID Platform QoS Enforcement Information
+
+ @param EAX CPUID_PLATFORM_QOS_ENFORCEMENT (0x10).
+ @param ECX CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF (0x00).
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF (0x01).
+ Additional sub leafs 1..n based in RESID from sub leaf 0x00.
+**/
+#define CPUID_PLATFORM_QOS_ENFORCEMENT 0x10
+
+/**
+ CPUID Platform QoS Enforcement Information
+
+ @param EAX CPUID_PLATFORM_QOS_ENFORCEMENT (0x10)
+ @param ECX CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF (0x00).
+
+ @retval EAX Reserved.
+ @retval EBX L3 Cache QoS Enforcement information described by the
+ type CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX.
+ @retval ECX Reserved.
+ @retval EDX Reserved.
+
+ <b>Example usage</b>
+ @code
+ CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX Ebx;
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF,
+ NULL, &Ebx.Uint32, NULL, NULL
+ );
+ @endcode
+**/
+#define CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF 0x00
+
+/**
+ CPUID Platform QoS Enforcement Information EBX for CPUID leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT, sub-leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF.
+**/
+typedef union {
+ ///
+ /// Individual bit fields
+ ///
+ struct {
+ UINT32 Reserved1:1;
+ ///
+ /// [Bit 1] Supports L3 Cache QoS Enforcement if 1.
+ ///
+ UINT32 L3CacheQosEnforcement:1;
+ UINT32 Reserved2:30;
+ } Bits;
+ ///
+ /// All bit fields as a 32-bit value
+ ///
+ UINT32 Uint32;
+} CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX;
+
+
+/**
+ CPUID Platform QoS Enforcement Information
+
+ @param EAX CPUID_PLATFORM_QOS_ENFORCEMENT (0x10)
+ @param ECX CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF (0x00)
+ Additional sub leafs 1..n based in RESID from sub leaf 0x00.
+
+ @retval EAX RESID L3 Cache3 QoS Enforcement information described by the
+ type CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX.
+ @retval EBX Bit-granular map of isolation/contention of allocation units.
+ @retval ECX RESID L3 Cache3 QoS Enforcement information described by the
+ type CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX.
+ @retval EDX RESID L3 Cache3 QoS Enforcement information described by the
+ type CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EDX.
+
+ <b>Example usage</b>
+ @code
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX Eax;
+ UINT32 Ebx;
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX Ecx;
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EDX Edx;
+
+ AsmCpuidEx (
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF,
+ &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32
+ );
+ @endcode
+**/
+#define CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF 0x01
+
+/**
+ CPUID Platform QoS Enforcement Information EAX for CPUID leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT, sub-leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF.
+**/
+typedef union {
+ ///
+ /// Individual bit fields
+ ///
+ struct {
+ ///
+ /// [Bits 3:0] Length of the capacity bit mask for the corresponding ResID.
+ ///
+ UINT32 CapacityLength:4;
+ UINT32 Reserved:28;
+ } Bits;
+ ///
+ /// All bit fields as a 32-bit value
+ ///
+ UINT32 Uint32;
+} CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX;
+
+/**
+ CPUID Platform QoS Enforcement Information ECX for CPUID leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT, sub-leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_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_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX;
+
+/**
+ CPUID Platform QoS Enforcement Information EDX for CPUID leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT, sub-leaf
+ #CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_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_PLATFORM_QOS_ENFORCEMENT_RESID_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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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;
+ UINT32 Reserved:28;
+ } 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.
+
+ <b>Example usage</b>
+ @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 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.
+ "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 Reserved.
+ @retval EDX Reserved.
+
+ <b>Example usage</b>
+ @code
+ UINT32 Eax;
+ UINT32 Ebx;
+
+ AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, NULL, 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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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.
+
+ <b>Example usage</b>
+ @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/Core/UefiCpuPkg/Include/Register/LocalApic.h b/Core/UefiCpuPkg/Include/Register/LocalApic.h
new file mode 100644
index 0000000000..346cce6756
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/LocalApic.h
@@ -0,0 +1,207 @@
+/** @file
+ IA32 Local APIC Definitions.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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
+
+//
+// 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/Core/UefiCpuPkg/Include/Register/Msr.h b/Core/UefiCpuPkg/Include/Register/Msr.h
new file mode 100644
index 0000000000..ffa6d4416a
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr.h
@@ -0,0 +1,48 @@
+/** @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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Chapter 35.
+
+**/
+
+#ifndef __MSR_H__
+#define __MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+#include <Register/Msr/Core2Msr.h>
+#include <Register/Msr/AtomMsr.h>
+#include <Register/Msr/SilvermontMsr.h>
+#include <Register/Msr/NehalemMsr.h>
+#include <Register/Msr/Xeon5600Msr.h>
+#include <Register/Msr/XeonE7Msr.h>
+#include <Register/Msr/SandyBridgeMsr.h>
+#include <Register/Msr/IvyBridgeMsr.h>
+#include <Register/Msr/HaswellMsr.h>
+#include <Register/Msr/HaswellEMsr.h>
+#include <Register/Msr/BroadwellMsr.h>
+#include <Register/Msr/XeonDMsr.h>
+#include <Register/Msr/SkylakeMsr.h>
+#include <Register/Msr/XeonPhiMsr.h>
+#include <Register/Msr/Pentium4Msr.h>
+#include <Register/Msr/CoreMsr.h>
+#include <Register/Msr/PentiumMMsr.h>
+#include <Register/Msr/P6Msr.h>
+#include <Register/Msr/PentiumMsr.h>
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/AtomMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/AtomMsr.h
new file mode 100644
index 0000000000..01e0d9a7a6
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/AtomMsr.h
@@ -0,0 +1,878 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-3.
+
+**/
+
+#ifndef __ATOM_MSR_H__
+#define __ATOM_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_ATOM_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PLATFORM_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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 0 From IP (R/W) One of eight pairs of last branch
+ record registers on the last branch record stack. This part of the stack
+ contains pointers to the source instruction for one of the last eight
+ branches, exceptions, or interrupts taken by the processor. See also: -
+ Last Branch Record Stack TOS at 1C9H - Section 17.12, "Last Branch,
+ Interrupt, and Exception Recording (Pentium M Processors).".
+
+ @param ECX MSR_ATOM_LASTBRANCH_n_FROM_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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 0 To IP (R/W) One of eight pairs of last branch
+ record registers on the last branch record stack. This part of the stack
+ contains pointers to the destination instruction for one of the last eight
+ branches, exceptions, or interrupts taken by the processor.
+
+ @param ECX MSR_ATOM_LASTBRANCH_n_TO_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_ATOM_FSB_FREQ_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_FSB_FREQ);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_ATOM_PERF_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PERF_STATUS);
+ AsmWriteMsr64 (MSR_ATOM_PERF_STATUS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_ATOM_THERM2_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_THERM2_CTL);
+ AsmWriteMsr64 (MSR_ATOM_THERM2_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+ ///
+ 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. Precise 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_ATOM_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_LER_TO_LIP);
+ @endcode
+**/
+#define MSR_ATOM_LER_TO_LIP 0x000001DE
+
+
+/**
+ Unique. See Table 35-2. See Section 18.4.2, "Global Counter Control
+ Facilities.".
+
+ @param ECX MSR_ATOM_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_ATOM_IA32_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_ATOM_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+
+/**
+ Unique. See Table 35-2. See Section 18.4.4, "Precise 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_ATOM_PEBS_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_ATOM_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_ATOM_PEBS_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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;
+
+
+/**
+ Shared. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_ATOM_MC3_CTL (0x0000040C)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC3_CTL);
+ AsmWriteMsr64 (MSR_ATOM_MC3_CTL, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC3_CTL 0x0000040C
+
+
+/**
+ Shared. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_ATOM_MC3_STATUS (0x0000040D)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC3_STATUS);
+ AsmWriteMsr64 (MSR_ATOM_MC3_STATUS, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC3_STATUS 0x0000040D
+
+
+/**
+ Shared. 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_ATOM_MC3_ADDR (0x0000040E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC3_ADDR);
+ AsmWriteMsr64 (MSR_ATOM_MC3_ADDR, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC3_ADDR 0x0000040E
+
+
+/**
+ Shared. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_ATOM_MC4_CTL (0x00000410)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC4_CTL);
+ AsmWriteMsr64 (MSR_ATOM_MC4_CTL, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC4_CTL 0x00000410
+
+
+/**
+ Shared. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_ATOM_MC4_STATUS (0x00000411)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC4_STATUS);
+ AsmWriteMsr64 (MSR_ATOM_MC4_STATUS, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC4_STATUS 0x00000411
+
+
+/**
+ Shared. 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_ATOM_MC4_ADDR (0x00000412)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_MC4_ADDR);
+ AsmWriteMsr64 (MSR_ATOM_MC4_ADDR, Msr);
+ @endcode
+**/
+#define MSR_ATOM_MC4_ADDR 0x00000412
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_PKG_C2_RESIDENCY);
+ AsmWriteMsr64 (MSR_ATOM_PKG_C2_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_PKG_C4_RESIDENCY);
+ AsmWriteMsr64 (MSR_ATOM_PKG_C4_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_ATOM_PKG_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_ATOM_PKG_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003FA
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h
new file mode 100644
index 0000000000..69c404eccd
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/BroadwellMsr.h
@@ -0,0 +1,265 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-12.
+
+**/
+
+#ifndef __BROADWELL_MSR_H__
+#define __BROADWELL_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ Thread. See Table 35-2. See Section 18.4.2, "Global Counter Control
+ Facilities.".
+
+ @param ECX MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS, Msr.Uint64);
+ @endcode
+**/
+#define MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+/**
+ MSR information returned for MSR index #MSR_BROADWELL_IA32_PERF_GLOBAL_STAUS
+**/
+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.4.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_STAUS_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. <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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_BROADWELL_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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;
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/Core2Msr.h b/Core/UefiCpuPkg/Include/Register/Msr/Core2Msr.h
new file mode 100644
index 0000000000..5fbde51bde
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/Core2Msr.h
@@ -0,0 +1,1325 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-2.
+
+**/
+
+#ifndef __CORE2_MSR_H__
+#define __CORE2_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PLATFORM_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_FEATURE_CONTROL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_FEATURE_CONTROL);
+ AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, Msr.Uint64);
+ @endcode
+**/
+#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. This part of the stack
+ contains pointers to the source instruction for one of the last four
+ branches, exceptions, or interrupts taken by the processor. See also: -
+ Last Branch Record Stack TOS at 1C9H - Section 17.12, "Last Branch,
+ Interrupt, and Exception Recording (Pentium M Processors).".
+
+ @param ECX MSR_CORE2_LASTBRANCH_n_FROM_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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 part of the stack
+ contains pointers to the destination instruction for one of the last four
+ branches, exceptions, or interrupts taken by the processor.
+
+ @param ECX MSR_CORE2_LASTBRANCH_n_TO_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_SMRR_PHYSBASE_REGISTER Msr;
+
+ Msr.Uint64 = 0;
+ AsmWriteMsr64 (MSR_CORE2_SMRR_PHYSBASE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_SMRR_PHYSMASK_REGISTER Msr;
+
+ Msr.Uint64 = 0;
+ AsmWriteMsr64 (MSR_CORE2_SMRR_PHYSMASK, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_FSB_FREQ_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_FSB_FREQ);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_PERF_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PERF_STATUS);
+ AsmWriteMsr64 (MSR_CORE2_PERF_STATUS, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_THERM2_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_THERM2_CTL);
+ AsmWriteMsr64 (MSR_CORE2_THERM2_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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. Precise 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_CORE2_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_LER_TO_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_PERF_FIXED_CTR0);
+ AsmWriteMsr64 (MSR_CORE2_PERF_FIXED_CTR0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_PERF_CAPABILITIES_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PERF_CAPABILITIES);
+ AsmWriteMsr64 (MSR_CORE2_PERF_CAPABILITIES, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_PERF_FIXED_CTR_CTRL);
+ AsmWriteMsr64 (MSR_CORE2_PERF_FIXED_CTR_CTRL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_PERF_FIXED_CTR_CTRL 0x0000038D
+
+
+/**
+ Unique. See Table 35-2. See Section 18.4.2, "Global Counter Control
+ Facilities.".
+
+ @param ECX MSR_CORE2_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_CORE2_IA32_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+
+/**
+ Unique. See Section 18.4.2, "Global Counter Control Facilities.".
+
+ @param ECX MSR_CORE2_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_PERF_GLOBAL_STAUS 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_CTRL);
+ AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_PERF_GLOBAL_OVF_CTRL);
+ AsmWriteMsr64 (MSR_CORE2_PERF_GLOBAL_OVF_CTRL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_PERF_GLOBAL_OVF_CTRL 0x00000390
+
+
+/**
+ Unique. See Table 35-2. See Section 18.4.4, "Precise 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE2_PEBS_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE2_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_CORE2_PEBS_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_CORE2_MC4_CTL (0x0000040C)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC4_CTL);
+ AsmWriteMsr64 (MSR_CORE2_MC4_CTL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC4_CTL 0x0000040C
+
+
+/**
+ Unique. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_CORE2_MC4_STATUS (0x0000040D)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC4_STATUS);
+ AsmWriteMsr64 (MSR_CORE2_MC4_STATUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_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_CORE2_MC4_ADDR (0x0000040E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC4_ADDR);
+ AsmWriteMsr64 (MSR_CORE2_MC4_ADDR, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC4_ADDR 0x0000040E
+
+
+/**
+ See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_CORE2_MC3_CTL (0x00000410)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC3_CTL);
+ AsmWriteMsr64 (MSR_CORE2_MC3_CTL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC3_CTL 0x00000410
+
+
+/**
+ See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_CORE2_MC3_STATUS (0x00000411)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC3_STATUS);
+ AsmWriteMsr64 (MSR_CORE2_MC3_STATUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC3_STATUS 0x00000411
+
+
+/**
+ 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_CORE2_MC3_ADDR (0x00000412)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC3_ADDR);
+ AsmWriteMsr64 (MSR_CORE2_MC3_ADDR, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC3_ADDR 0x00000412
+
+
+/**
+ Unique.
+
+ @param ECX MSR_CORE2_MC3_MISC (0x00000413)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC3_MISC);
+ AsmWriteMsr64 (MSR_CORE2_MC3_MISC, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC3_MISC 0x00000413
+
+
+/**
+ Unique.
+
+ @param ECX MSR_CORE2_MC5_CTL (0x00000414)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC5_CTL);
+ AsmWriteMsr64 (MSR_CORE2_MC5_CTL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC5_CTL 0x00000414
+
+
+/**
+ Unique.
+
+ @param ECX MSR_CORE2_MC5_STATUS (0x00000415)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC5_STATUS);
+ AsmWriteMsr64 (MSR_CORE2_MC5_STATUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC5_STATUS 0x00000415
+
+
+/**
+ Unique.
+
+ @param ECX MSR_CORE2_MC5_ADDR (0x00000416)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC5_ADDR);
+ AsmWriteMsr64 (MSR_CORE2_MC5_ADDR, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC5_ADDR 0x00000416
+
+
+/**
+ Unique.
+
+ @param ECX MSR_CORE2_MC5_MISC (0x00000417)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC5_MISC);
+ AsmWriteMsr64 (MSR_CORE2_MC5_MISC, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC5_MISC 0x00000417
+
+
+/**
+ Unique. Apply to Intel Xeon processor 7400 series (processor signature
+ 06_1D) only. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS." and Chapter 23.
+
+ @param ECX MSR_CORE2_MC6_STATUS (0x00000419)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_MC6_STATUS);
+ AsmWriteMsr64 (MSR_CORE2_MC6_STATUS, Msr);
+ @endcode
+**/
+#define MSR_CORE2_MC6_STATUS 0x00000419
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_EMON_L3_CTR_CTL0);
+ AsmWriteMsr64 (MSR_CORE2_EMON_L3_CTR_CTL0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE2_EMON_L3_GL_CTL);
+ AsmWriteMsr64 (MSR_CORE2_EMON_L3_GL_CTL, Msr);
+ @endcode
+**/
+#define MSR_CORE2_EMON_L3_GL_CTL 0x000107D8
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/CoreMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/CoreMsr.h
new file mode 100644
index 0000000000..11956fb7f5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/CoreMsr.h
@@ -0,0 +1,1074 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-17.
+
+**/
+
+#ifndef __CORE_MSR_H__
+#define __CORE_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ Unique. See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_P5_MC_ADDR);
+ AsmWriteMsr64 (MSR_CORE_P5_MC_ADDR, Msr);
+ @endcode
+**/
+#define MSR_CORE_P5_MC_ADDR 0x00000000
+
+
+/**
+ Unique. See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_P5_MC_TYPE);
+ AsmWriteMsr64 (MSR_CORE_P5_MC_TYPE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.12, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_LASTBRANCH_0);
+ AsmWriteMsr64 (MSR_CORE_LASTBRANCH_0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE_FSB_FREQ_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE_FSB_FREQ);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE_THERM2_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE_THERM2_CTL);
+ AsmWriteMsr64 (MSR_CORE_THERM2_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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 3.
+ ///
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_CORE_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_LER_TO_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRPHYSBASE0);
+ AsmWriteMsr64 (MSR_CORE_MTRRPHYSBASE0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRPHYSMASK0);
+ AsmWriteMsr64 (MSR_CORE_MTRRPHYSMASK0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX64K_00000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX64K_00000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX16K_80000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX16K_80000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX16K_A0000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX16K_A0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_C0000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_C0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_C8000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_C8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_D0000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_D0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_D8000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_D8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_E0000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_E0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_E8000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_E8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_F0000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_F0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MTRRFIX4K_F8000);
+ AsmWriteMsr64 (MSR_CORE_MTRRFIX4K_F8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC4_CTL);
+ AsmWriteMsr64 (MSR_CORE_MC4_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC4_STATUS);
+ AsmWriteMsr64 (MSR_CORE_MC4_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC4_ADDR);
+ AsmWriteMsr64 (MSR_CORE_MC4_ADDR, Msr);
+ @endcode
+**/
+#define MSR_CORE_MC4_ADDR 0x0000040E
+
+
+/**
+ See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_CORE_MC3_CTL (0x00000410)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC3_CTL);
+ AsmWriteMsr64 (MSR_CORE_MC3_CTL, Msr);
+ @endcode
+**/
+#define MSR_CORE_MC3_CTL 0x00000410
+
+
+/**
+ See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_CORE_MC3_STATUS (0x00000411)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC3_STATUS);
+ AsmWriteMsr64 (MSR_CORE_MC3_STATUS, Msr);
+ @endcode
+**/
+#define MSR_CORE_MC3_STATUS 0x00000411
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC3_ADDR);
+ AsmWriteMsr64 (MSR_CORE_MC3_ADDR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC3_MISC);
+ AsmWriteMsr64 (MSR_CORE_MC3_MISC, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC5_CTL);
+ AsmWriteMsr64 (MSR_CORE_MC5_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC5_STATUS);
+ AsmWriteMsr64 (MSR_CORE_MC5_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC5_ADDR);
+ AsmWriteMsr64 (MSR_CORE_MC5_ADDR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_CORE_MC5_MISC);
+ AsmWriteMsr64 (MSR_CORE_MC5_MISC, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_CORE_IA32_EFER_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_EFER);
+ AsmWriteMsr64 (MSR_CORE_IA32_EFER, Msr.Uint64);
+ @endcode
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h
new file mode 100644
index 0000000000..ae9f406863
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/HaswellEMsr.h
@@ -0,0 +1,5995 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-11.
+
+**/
+
+#ifndef __HASWELL_E_MSR_H__
+#define __HASWELL_E_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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. <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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_E_IA32_MCG_CAP_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_IA32_MCG_CAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_E_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_E_TURBO_RATIO_LIMIT1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_E_TURBO_RATIO_LIMIT2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_TURBO_RATIO_LIMIT2);
+ @endcode
+**/
+#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. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ * Bank MC5 reports MC error from the Intel QPI 0 module.
+ * Bank MC6 reports MC error from the integrated I/O module.
+ * Bank MC7 reports MC error from the home agent HA 0.
+ * Bank MC8 reports MC error from the home agent HA 1.
+ * Banks MC9 through MC16 report MC error from each channel of the integrated
+ memory controllers.
+ * Bank MC17 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo0, CBo3, CBo6, CBo9, CBo12, CBo15.
+ * Bank MC18 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo1, CBo4, CBo7, CBo10, CBo13, CBo16.
+ * Bank MC19 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo2, CBo5, CBo8, CBo11, CBo14, CBo17.
+ * Bank MC20 reports MC error from the Intel QPI 1 module.
+ * Bank MC21 reports MC error from the Intel QPI 2 module.
+
+ @param ECX MSR_HASWELL_E_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_MC5_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_MC5_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_HASWELL_E_MC5_CTL 0x00000414
+#define MSR_HASWELL_E_MC6_CTL 0x00000418
+#define MSR_HASWELL_E_MC7_CTL 0x0000041C
+#define MSR_HASWELL_E_MC8_CTL 0x00000420
+#define MSR_HASWELL_E_MC9_CTL 0x00000424
+#define MSR_HASWELL_E_MC10_CTL 0x00000428
+#define MSR_HASWELL_E_MC11_CTL 0x0000042C
+#define MSR_HASWELL_E_MC12_CTL 0x00000430
+#define MSR_HASWELL_E_MC13_CTL 0x00000434
+#define MSR_HASWELL_E_MC14_CTL 0x00000438
+#define MSR_HASWELL_E_MC15_CTL 0x0000043C
+#define MSR_HASWELL_E_MC16_CTL 0x00000440
+#define MSR_HASWELL_E_MC17_CTL 0x00000444
+#define MSR_HASWELL_E_MC18_CTL 0x00000448
+#define MSR_HASWELL_E_MC19_CTL 0x0000044C
+#define MSR_HASWELL_E_MC20_CTL 0x00000450
+#define MSR_HASWELL_E_MC21_CTL 0x00000454
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_HASWELL_E_MCi_STATUS
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_MC5_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_MC5_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_HASWELL_E_MC5_STATUS 0x00000415
+#define MSR_HASWELL_E_MC6_STATUS 0x00000419
+#define MSR_HASWELL_E_MC7_STATUS 0x0000041D
+#define MSR_HASWELL_E_MC8_STATUS 0x00000421
+#define MSR_HASWELL_E_MC9_STATUS 0x00000425
+#define MSR_HASWELL_E_MC10_STATUS 0x00000429
+#define MSR_HASWELL_E_MC11_STATUS 0x0000042D
+#define MSR_HASWELL_E_MC12_STATUS 0x00000431
+#define MSR_HASWELL_E_MC13_STATUS 0x00000435
+#define MSR_HASWELL_E_MC14_STATUS 0x00000439
+#define MSR_HASWELL_E_MC15_STATUS 0x0000043D
+#define MSR_HASWELL_E_MC16_STATUS 0x00000441
+#define MSR_HASWELL_E_MC17_STATUS 0x00000445
+#define MSR_HASWELL_E_MC18_STATUS 0x00000449
+#define MSR_HASWELL_E_MC19_STATUS 0x0000044D
+#define MSR_HASWELL_E_MC20_STATUS 0x00000451
+#define MSR_HASWELL_E_MC21_STATUS 0x00000455
+/// @}
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_HASWELL_E_MCi_ADDR
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_MC5_ADDR);
+ AsmWriteMsr64 (MSR_HASWELL_E_MC5_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_HASWELL_E_MC5_ADDR 0x00000416
+#define MSR_HASWELL_E_MC6_ADDR 0x0000041A
+#define MSR_HASWELL_E_MC7_ADDR 0x0000041E
+#define MSR_HASWELL_E_MC8_ADDR 0x00000422
+#define MSR_HASWELL_E_MC9_ADDR 0x00000426
+#define MSR_HASWELL_E_MC10_ADDR 0x0000042A
+#define MSR_HASWELL_E_MC11_ADDR 0x0000042E
+#define MSR_HASWELL_E_MC12_ADDR 0x00000432
+#define MSR_HASWELL_E_MC13_ADDR 0x00000436
+#define MSR_HASWELL_E_MC14_ADDR 0x0000043A
+#define MSR_HASWELL_E_MC15_ADDR 0x0000043E
+#define MSR_HASWELL_E_MC16_ADDR 0x00000442
+#define MSR_HASWELL_E_MC17_ADDR 0x00000446
+#define MSR_HASWELL_E_MC18_ADDR 0x0000044A
+#define MSR_HASWELL_E_MC19_ADDR 0x0000044E
+#define MSR_HASWELL_E_MC20_ADDR 0x00000452
+#define MSR_HASWELL_E_MC21_ADDR 0x00000456
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_HASWELL_E_MCi_MISC
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_MC5_MISC);
+ AsmWriteMsr64 (MSR_HASWELL_E_MC5_MISC, Msr);
+ @endcode
+ @{
+**/
+#define MSR_HASWELL_E_MC5_MISC 0x00000417
+#define MSR_HASWELL_E_MC6_MISC 0x0000041B
+#define MSR_HASWELL_E_MC7_MISC 0x0000041F
+#define MSR_HASWELL_E_MC8_MISC 0x00000423
+#define MSR_HASWELL_E_MC9_MISC 0x00000427
+#define MSR_HASWELL_E_MC10_MISC 0x0000042B
+#define MSR_HASWELL_E_MC11_MISC 0x0000042F
+#define MSR_HASWELL_E_MC12_MISC 0x00000433
+#define MSR_HASWELL_E_MC13_MISC 0x00000437
+#define MSR_HASWELL_E_MC14_MISC 0x0000043B
+#define MSR_HASWELL_E_MC15_MISC 0x0000043F
+#define MSR_HASWELL_E_MC16_MISC 0x00000443
+#define MSR_HASWELL_E_MC17_MISC 0x00000447
+#define MSR_HASWELL_E_MC18_MISC 0x0000044B
+#define MSR_HASWELL_E_MC19_MISC 0x0000044F
+#define MSR_HASWELL_E_MC20_MISC 0x00000453
+#define MSR_HASWELL_E_MC21_MISC 0x00000457
+/// @}
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_E_RAPL_POWER_UNIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_E_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_HASWELL_E_DRAM_POWER_LIMIT, Msr);
+ @endcode
+**/
+#define MSR_HASWELL_E_DRAM_POWER_LIMIT 0x00000618
+
+
+/**
+ Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.".
+
+ @param ECX MSR_HASWELL_E_DRAM_ENERGY_STATUS (0x00000619)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#define MSR_HASWELL_E_DRAM_ENERGY_STATUS 0x00000619
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_DRAM_POWER_INFO);
+ AsmWriteMsr64 (MSR_HASWELL_E_DRAM_POWER_INFO, Msr);
+ @endcode
+**/
+#define MSR_HASWELL_E_DRAM_POWER_INFO 0x0000061C
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.PQM[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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CONFIG);
+ AsmWriteMsr64 (MSR_HASWELL_E_PMON_GLOBAL_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_UCLK_FIXED_CTR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_U_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_U_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_PCU_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_PCU_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S2_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S2_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_S3_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_S3_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C2_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C2_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C3_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C3_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C4_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C4_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C5_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C5_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C6_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C6_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C7_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C7_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C8_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C8_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C9_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C9_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C10_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C10_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C11_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C11_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C12_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C12_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C13_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C13_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C14_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C14_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C15_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C15_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C16_PMON_CTR3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C16_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_E_C17_PMON_CTR0);
+ AsmWriteMsr64 (MSR_HASWELL_E_C17_PMON_CTR0, Msr);
+ @endcode
+ @{
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h
new file mode 100644
index 0000000000..78915ec7a4
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/HaswellMsr.h
@@ -0,0 +1,2575 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-10.
+
+**/
+
+#ifndef __HASWELL_MSR_H__
+#define __HASWELL_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_PLATFORM_INFO_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PLATFORM_INFO);
+ AsmWriteMsr64 (MSR_HASWELL_PLATFORM_INFO, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_IA32_PERFEVTSEL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_IA32_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_IA32_PERFEVTSEL0, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_IA32_PERFEVTSEL2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_IA32_PERFEVTSEL2);
+ AsmWriteMsr64 (MSR_HASWELL_IA32_PERFEVTSEL2, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_LBR_SELECT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_LBR_SELECT);
+ AsmWriteMsr64 (MSR_HASWELL_LBR_SELECT, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_PKGC_IRTL1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKGC_IRTL1);
+ AsmWriteMsr64 (MSR_HASWELL_PKGC_IRTL1, Msr.Uint64);
+ @endcode
+**/
+#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. 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_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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_PKGC_IRTL2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_PKGC_IRTL2);
+ AsmWriteMsr64 (MSR_HASWELL_PKGC_IRTL2, Msr.Uint64);
+ @endcode
+**/
+#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. 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_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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_PKG_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_CONFIG_TDP_NOMINAL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_NOMINAL);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_CONFIG_TDP_LEVEL1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_LEVEL1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_CONFIG_TDP_LEVEL2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_CONFIG_TDP_LEVEL2);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ Package. Silicon Debug Feature Control (R/W) See Table 35-2.
+
+ @param ECX MSR_HASWELL_IA32_DEBUG_FEATURE (0x00000C80)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_IA32_DEBUG_FEATURE);
+ AsmWriteMsr64 (MSR_HASWELL_IA32_DEBUG_FEATURE, Msr);
+ @endcode
+**/
+#define MSR_HASWELL_IA32_DEBUG_FEATURE 0x00000C80
+
+
+/**
+ 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. <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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_UNC_CBO_CONFIG_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_CONFIG);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_ARB_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_SMM_DELAYED);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_SMM_BLOCKED);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_HASWELL_RAPL_POWER_UNIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_HASWELL_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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. 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_PP1_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_HASWELL_PP1_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_PP1_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_PP1_POLICY);
+ AsmWriteMsr64 (MSR_HASWELL_PP1_POLICY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_0_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_1_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_2_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR0);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR1);
+ AsmWriteMsr64 (MSR_HASWELL_UNC_CBO_3_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h
new file mode 100644
index 0000000000..0b08c0a8c6
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/IvyBridgeMsr.h
@@ -0,0 +1,2830 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-9.
+
+**/
+
+#ifndef __IVY_BRIDGE_MSR_H__
+#define __IVY_BRIDGE_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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. 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_NOMINAL);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_CONFIG_TDP_LEVEL2);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_TURBO_RATIO_LIMIT1);
+ @endcode
+**/
+#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. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.". Bank MC5 reports MC error from the Intel
+ QPI module.
+
+ * Bank MC6 reports MC error from the integrated I/O module.
+ * Banks MC7 and MC 8 report MC error from the two home agents.
+ * Banks MC9 through MC 16 report MC error from each channel of the integrated
+ memory controllers.
+ * Banks MC17 through MC31 reports MC error from a specific CBo
+ (core broadcast) and its corresponding slice of L3.
+
+ @param ECX MSR_IVY_BRIDGE_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_MC5_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_MC5_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_IVY_BRIDGE_MC5_CTL 0x00000414
+#define MSR_IVY_BRIDGE_MC6_CTL 0x00000418
+#define MSR_IVY_BRIDGE_MC7_CTL 0x0000041C
+#define MSR_IVY_BRIDGE_MC8_CTL 0x00000420
+#define MSR_IVY_BRIDGE_MC9_CTL 0x00000424
+#define MSR_IVY_BRIDGE_MC10_CTL 0x00000428
+#define MSR_IVY_BRIDGE_MC11_CTL 0x0000042C
+#define MSR_IVY_BRIDGE_MC12_CTL 0x00000430
+#define MSR_IVY_BRIDGE_MC13_CTL 0x00000434
+#define MSR_IVY_BRIDGE_MC14_CTL 0x00000438
+#define MSR_IVY_BRIDGE_MC15_CTL 0x0000043C
+#define MSR_IVY_BRIDGE_MC16_CTL 0x00000440
+#define MSR_IVY_BRIDGE_MC17_CTL 0x00000444
+#define MSR_IVY_BRIDGE_MC18_CTL 0x00000448
+#define MSR_IVY_BRIDGE_MC19_CTL 0x0000044C
+#define MSR_IVY_BRIDGE_MC20_CTL 0x00000450
+#define MSR_IVY_BRIDGE_MC21_CTL 0x00000454
+#define MSR_IVY_BRIDGE_MC22_CTL 0x00000458
+#define MSR_IVY_BRIDGE_MC23_CTL 0x0000045C
+#define MSR_IVY_BRIDGE_MC24_CTL 0x00000460
+#define MSR_IVY_BRIDGE_MC25_CTL 0x00000464
+#define MSR_IVY_BRIDGE_MC26_CTL 0x00000468
+#define MSR_IVY_BRIDGE_MC27_CTL 0x0000046C
+#define MSR_IVY_BRIDGE_MC28_CTL 0x00000470
+#define MSR_IVY_BRIDGE_MC29_CTL 0x00000474
+#define MSR_IVY_BRIDGE_MC30_CTL 0x00000478
+#define MSR_IVY_BRIDGE_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 MC20 reports MC error from a specific CBo (core broadcast) and
+ its corresponding slice of L3.
+
+ @param ECX MSR_IVY_BRIDGE_MCi_STATUS
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_MC5_STATUS);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_MC5_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_IVY_BRIDGE_MC5_STATUS 0x00000415
+#define MSR_IVY_BRIDGE_MC6_STATUS 0x00000419
+#define MSR_IVY_BRIDGE_MC7_STATUS 0x0000041D
+#define MSR_IVY_BRIDGE_MC8_STATUS 0x00000421
+#define MSR_IVY_BRIDGE_MC9_STATUS 0x00000425
+#define MSR_IVY_BRIDGE_MC10_STATUS 0x00000429
+#define MSR_IVY_BRIDGE_MC11_STATUS 0x0000042D
+#define MSR_IVY_BRIDGE_MC12_STATUS 0x00000431
+#define MSR_IVY_BRIDGE_MC13_STATUS 0x00000435
+#define MSR_IVY_BRIDGE_MC14_STATUS 0x00000439
+#define MSR_IVY_BRIDGE_MC15_STATUS 0x0000043D
+#define MSR_IVY_BRIDGE_MC16_STATUS 0x00000441
+#define MSR_IVY_BRIDGE_MC17_STATUS 0x00000445
+#define MSR_IVY_BRIDGE_MC18_STATUS 0x00000449
+#define MSR_IVY_BRIDGE_MC19_STATUS 0x0000044D
+#define MSR_IVY_BRIDGE_MC20_STATUS 0x00000451
+#define MSR_IVY_BRIDGE_MC21_STATUS 0x00000455
+#define MSR_IVY_BRIDGE_MC22_STATUS 0x00000459
+#define MSR_IVY_BRIDGE_MC23_STATUS 0x0000045D
+#define MSR_IVY_BRIDGE_MC24_STATUS 0x00000461
+#define MSR_IVY_BRIDGE_MC25_STATUS 0x00000465
+#define MSR_IVY_BRIDGE_MC26_STATUS 0x00000469
+#define MSR_IVY_BRIDGE_MC27_STATUS 0x0000046D
+#define MSR_IVY_BRIDGE_MC28_STATUS 0x00000471
+#define MSR_IVY_BRIDGE_MC29_STATUS 0x00000475
+#define MSR_IVY_BRIDGE_MC30_STATUS 0x00000479
+#define MSR_IVY_BRIDGE_MC31_STATUS 0x0000047D
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_IVY_BRIDGE_MCi_ADDR
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_MC5_ADDR);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_MC5_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_IVY_BRIDGE_MC5_ADDR 0x00000416
+#define MSR_IVY_BRIDGE_MC6_ADDR 0x0000041A
+#define MSR_IVY_BRIDGE_MC7_ADDR 0x0000041E
+#define MSR_IVY_BRIDGE_MC8_ADDR 0x00000422
+#define MSR_IVY_BRIDGE_MC9_ADDR 0x00000426
+#define MSR_IVY_BRIDGE_MC10_ADDR 0x0000042A
+#define MSR_IVY_BRIDGE_MC11_ADDR 0x0000042E
+#define MSR_IVY_BRIDGE_MC12_ADDR 0x00000432
+#define MSR_IVY_BRIDGE_MC13_ADDR 0x00000436
+#define MSR_IVY_BRIDGE_MC14_ADDR 0x0000043A
+#define MSR_IVY_BRIDGE_MC15_ADDR 0x0000043E
+#define MSR_IVY_BRIDGE_MC16_ADDR 0x00000442
+#define MSR_IVY_BRIDGE_MC17_ADDR 0x00000446
+#define MSR_IVY_BRIDGE_MC18_ADDR 0x0000044A
+#define MSR_IVY_BRIDGE_MC19_ADDR 0x0000044E
+#define MSR_IVY_BRIDGE_MC20_ADDR 0x00000452
+#define MSR_IVY_BRIDGE_MC21_ADDR 0x00000456
+#define MSR_IVY_BRIDGE_MC22_ADDR 0x0000045A
+#define MSR_IVY_BRIDGE_MC23_ADDR 0x0000045E
+#define MSR_IVY_BRIDGE_MC24_ADDR 0x00000462
+#define MSR_IVY_BRIDGE_MC25_ADDR 0x00000466
+#define MSR_IVY_BRIDGE_MC26_ADDR 0x0000046A
+#define MSR_IVY_BRIDGE_MC27_ADDR 0x0000046E
+#define MSR_IVY_BRIDGE_MC28_ADDR 0x00000472
+#define MSR_IVY_BRIDGE_MC29_ADDR 0x00000476
+#define MSR_IVY_BRIDGE_MC30_ADDR 0x0000047A
+#define MSR_IVY_BRIDGE_MC31_ADDR 0x0000047E
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_IVY_BRIDGE_MCi_MISC
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_MC5_MISC);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_MC5_MISC, Msr);
+ @endcode
+ @{
+**/
+#define MSR_IVY_BRIDGE_MC5_MISC 0x00000417
+#define MSR_IVY_BRIDGE_MC6_MISC 0x0000041B
+#define MSR_IVY_BRIDGE_MC7_MISC 0x0000041F
+#define MSR_IVY_BRIDGE_MC8_MISC 0x00000423
+#define MSR_IVY_BRIDGE_MC9_MISC 0x00000427
+#define MSR_IVY_BRIDGE_MC10_MISC 0x0000042B
+#define MSR_IVY_BRIDGE_MC11_MISC 0x0000042F
+#define MSR_IVY_BRIDGE_MC12_MISC 0x00000433
+#define MSR_IVY_BRIDGE_MC13_MISC 0x00000437
+#define MSR_IVY_BRIDGE_MC14_MISC 0x0000043B
+#define MSR_IVY_BRIDGE_MC15_MISC 0x0000043F
+#define MSR_IVY_BRIDGE_MC16_MISC 0x00000443
+#define MSR_IVY_BRIDGE_MC17_MISC 0x00000447
+#define MSR_IVY_BRIDGE_MC18_MISC 0x0000044B
+#define MSR_IVY_BRIDGE_MC19_MISC 0x0000044F
+#define MSR_IVY_BRIDGE_MC20_MISC 0x00000453
+#define MSR_IVY_BRIDGE_MC21_MISC 0x00000457
+#define MSR_IVY_BRIDGE_MC22_MISC 0x0000045B
+#define MSR_IVY_BRIDGE_MC23_MISC 0x0000045F
+#define MSR_IVY_BRIDGE_MC24_MISC 0x00000463
+#define MSR_IVY_BRIDGE_MC25_MISC 0x00000467
+#define MSR_IVY_BRIDGE_MC26_MISC 0x0000046B
+#define MSR_IVY_BRIDGE_MC27_MISC 0x0000046F
+#define MSR_IVY_BRIDGE_MC28_MISC 0x00000473
+#define MSR_IVY_BRIDGE_MC29_MISC 0x00000477
+#define MSR_IVY_BRIDGE_MC30_MISC 0x0000047B
+#define MSR_IVY_BRIDGE_MC31_MISC 0x0000047F
+/// @}
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_IVY_BRIDGE_IA32_MC6_MISC_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_IA32_MC6_MISC);
+ @endcode
+**/
+#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. 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PKG_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_INFO);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_DRAM_POWER_INFO, Msr);
+ @endcode
+**/
+#define MSR_IVY_BRIDGE_DRAM_POWER_INFO 0x0000061C
+
+
+/**
+ Thread. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_PMON_GLOBAL_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_U_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_U_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_PCU_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C0_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C1_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C2_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C3_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C4_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C5_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C6_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C7_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C8_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C9_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C10_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C11_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C12_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C13_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR0);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR2);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR3);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1);
+ AsmWriteMsr64 (MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1, Msr);
+ @endcode
+**/
+#define MSR_IVY_BRIDGE_C14_PMON_BOX_FILTER1 0x00000EDA
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h
new file mode 100644
index 0000000000..cc24a232c5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/NehalemMsr.h
@@ -0,0 +1,7196 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-5.
+
+**/
+
+#ifndef __NEHALEM_MSR_H__
+#define __NEHALEM_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_SMI_COUNT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_SMI_COUNT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_PLATFORM_INFO_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_INFO);
+ AsmWriteMsr64 (MSR_NEHALEM_PLATFORM_INFO, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+ 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_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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+ ///
+ 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. Precise 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_TEMPERATURE_TARGET_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TEMPERATURE_TARGET);
+ AsmWriteMsr64 (MSR_NEHALEM_TEMPERATURE_TARGET, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_OFFCORE_RSP_0);
+ AsmWriteMsr64 (MSR_NEHALEM_OFFCORE_RSP_0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.6.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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_LBR_SELECT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_LBR_SELECT);
+ AsmWriteMsr64 (MSR_NEHALEM_LBR_SELECT, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_LER_TO_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_POWER_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_POWER_CTL);
+ AsmWriteMsr64 (MSR_NEHALEM_POWER_CTL, Msr.Uint64);
+ @endcode
+**/
+#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. See Table 35-2. See Section 18.4.2, "Global Counter Control
+ Facilities.".
+
+ @param ECX MSR_NEHALEM_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_NEHALEM_IA32_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+
+/**
+ Thread. (RO).
+
+ @param ECX MSR_NEHALEM_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_NEHALEM_PERF_GLOBAL_STAUS_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_NEHALEM_PERF_GLOBAL_STAUS_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_PERF_GLOBAL_STAUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PERF_GLOBAL_STAUS);
+ @endcode
+**/
+#define MSR_NEHALEM_PERF_GLOBAL_STAUS 0x0000038E
+
+/**
+ MSR information returned for MSR index #MSR_NEHALEM_PERF_GLOBAL_STAUS
+**/
+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_STAUS_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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.7.1.1, "Precise 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_NEHALEM_PEBS_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_NEHALEM_PEBS_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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.7.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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C3_RESIDENCY);
+ AsmWriteMsr64 (MSR_NEHALEM_PKG_C3_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_NEHALEM_PKG_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_PKG_C7_RESIDENCY);
+ AsmWriteMsr64 (MSR_NEHALEM_PKG_C7_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_CORE_C3_RESIDENCY);
+ AsmWriteMsr64 (MSR_NEHALEM_CORE_C3_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_CORE_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_NEHALEM_CORE_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_CORE_C6_RESIDENCY 0x000003FD
+
+
+/**
+ See Section 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_NEHALEM_MCi_MISC
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_MC0_MISC);
+ AsmWriteMsr64 (MSR_NEHALEM_MC0_MISC, Msr);
+ @endcode
+ @{
+**/
+#define MSR_NEHALEM_MC0_MISC 0x00000403
+#define MSR_NEHALEM_MC1_MISC 0x00000407
+#define MSR_NEHALEM_MC2_MISC 0x0000040B
+#define MSR_NEHALEM_MC3_MISC 0x0000040F
+#define MSR_NEHALEM_MC4_MISC 0x00000413
+#define MSR_NEHALEM_MC5_MISC 0x00000417
+#define MSR_NEHALEM_MC6_MISC 0x0000041B
+#define MSR_NEHALEM_MC7_MISC 0x0000041F
+#define MSR_NEHALEM_MC8_MISC 0x00000423
+#define MSR_NEHALEM_MC9_MISC 0x00000427
+#define MSR_NEHALEM_MC10_MISC 0x0000042B
+#define MSR_NEHALEM_MC11_MISC 0x0000042F
+#define MSR_NEHALEM_MC12_MISC 0x00000433
+#define MSR_NEHALEM_MC13_MISC 0x00000437
+#define MSR_NEHALEM_MC14_MISC 0x0000043B
+#define MSR_NEHALEM_MC15_MISC 0x0000043F
+#define MSR_NEHALEM_MC16_MISC 0x00000443
+#define MSR_NEHALEM_MC17_MISC 0x00000447
+#define MSR_NEHALEM_MC18_MISC 0x0000044B
+#define MSR_NEHALEM_MC19_MISC 0x0000044F
+#define MSR_NEHALEM_MC20_MISC 0x00000453
+#define MSR_NEHALEM_MC21_MISC 0x00000457
+/// @}
+
+
+/**
+ See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_NEHALEM_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_MC3_CTL);
+ AsmWriteMsr64 (MSR_NEHALEM_MC3_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_NEHALEM_MC3_CTL 0x0000040C
+#define MSR_NEHALEM_MC4_CTL 0x00000410
+#define MSR_NEHALEM_MC5_CTL 0x00000414
+#define MSR_NEHALEM_MC6_CTL 0x00000418
+#define MSR_NEHALEM_MC7_CTL 0x0000041C
+#define MSR_NEHALEM_MC8_CTL 0x00000420
+#define MSR_NEHALEM_MC9_CTL 0x00000424
+#define MSR_NEHALEM_MC10_CTL 0x00000428
+#define MSR_NEHALEM_MC11_CTL 0x0000042C
+#define MSR_NEHALEM_MC12_CTL 0x00000430
+#define MSR_NEHALEM_MC13_CTL 0x00000434
+#define MSR_NEHALEM_MC14_CTL 0x00000438
+#define MSR_NEHALEM_MC15_CTL 0x0000043C
+#define MSR_NEHALEM_MC16_CTL 0x00000440
+#define MSR_NEHALEM_MC17_CTL 0x00000444
+#define MSR_NEHALEM_MC18_CTL 0x00000448
+#define MSR_NEHALEM_MC19_CTL 0x0000044C
+#define MSR_NEHALEM_MC20_CTL 0x00000450
+#define MSR_NEHALEM_MC21_CTL 0x00000454
+/// @}
+
+
+/**
+ See Section 15.3.2.2, "IA32_MCi_STATUS MSRS," and Chapter 16.
+
+ @param ECX MSR_NEHALEM_MCi_STATUS (0x0000040D)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_MC3_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_MC3_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_NEHALEM_MC3_STATUS 0x0000040D
+#define MSR_NEHALEM_MC4_STATUS 0x00000411
+#define MSR_NEHALEM_MC5_STATUS 0x00000415
+#define MSR_NEHALEM_MC6_STATUS 0x00000419
+#define MSR_NEHALEM_MC7_STATUS 0x0000041D
+#define MSR_NEHALEM_MC8_STATUS 0x00000421
+#define MSR_NEHALEM_MC9_STATUS 0x00000425
+#define MSR_NEHALEM_MC10_STATUS 0x00000429
+#define MSR_NEHALEM_MC11_STATUS 0x0000042D
+#define MSR_NEHALEM_MC12_STATUS 0x00000431
+#define MSR_NEHALEM_MC13_STATUS 0x00000435
+#define MSR_NEHALEM_MC14_STATUS 0x00000439
+#define MSR_NEHALEM_MC15_STATUS 0x0000043D
+#define MSR_NEHALEM_MC16_STATUS 0x00000441
+#define MSR_NEHALEM_MC17_STATUS 0x00000445
+#define MSR_NEHALEM_MC18_STATUS 0x00000449
+#define MSR_NEHALEM_MC19_STATUS 0x0000044D
+#define MSR_NEHALEM_MC20_STATUS 0x00000451
+#define MSR_NEHALEM_MC21_STATUS 0x00000455
+/// @}
+
+
+/**
+ Core. 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.
+
+ 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_NEHALEM_MC3_ADDR (0x0000040E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_MC3_ADDR);
+ AsmWriteMsr64 (MSR_NEHALEM_MC3_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_NEHALEM_MC3_ADDR 0x0000040E
+#define MSR_NEHALEM_MC4_ADDR 0x00000412
+#define MSR_NEHALEM_MC5_ADDR 0x00000416
+#define MSR_NEHALEM_MC6_ADDR 0x0000041A
+#define MSR_NEHALEM_MC7_ADDR 0x0000041E
+#define MSR_NEHALEM_MC8_ADDR 0x00000422
+#define MSR_NEHALEM_MC9_ADDR 0x00000426
+#define MSR_NEHALEM_MC10_ADDR 0x0000042A
+#define MSR_NEHALEM_MC11_ADDR 0x0000042E
+#define MSR_NEHALEM_MC12_ADDR 0x00000432
+#define MSR_NEHALEM_MC13_ADDR 0x00000436
+#define MSR_NEHALEM_MC14_ADDR 0x0000043A
+#define MSR_NEHALEM_MC15_ADDR 0x0000043E
+#define MSR_NEHALEM_MC16_ADDR 0x00000442
+#define MSR_NEHALEM_MC17_ADDR 0x00000446
+#define MSR_NEHALEM_MC18_ADDR 0x0000044A
+#define MSR_NEHALEM_MC19_ADDR 0x0000044E
+#define MSR_NEHALEM_MC20_ADDR 0x00000452
+#define MSR_NEHALEM_MC21_ADDR 0x00000456
+/// @}
+
+
+/**
+ 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 for one of the last
+ sixteen branches, exceptions, or interrupts taken by the processor. See
+ also: - Last Branch Record Stack TOS at 1C9H - Section 17.6.1, "LBR
+ Stack.".
+
+ @param ECX MSR_NEHALEM_LASTBRANCH_n_FROM_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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 for one of the last sixteen
+ branches, exceptions, or interrupts taken by the processor.
+
+ @param ECX MSR_NEHALEM_LASTBRANCH_n_TO_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_NEHALEM_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_CTRL 0x00000391
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_STATUS 0x00000392
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_PERF_GLOBAL_OVF_CTRL 0x00000393
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR0, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_FIXED_CTR0 0x00000394
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_FIXED_CTR_CTRL 0x00000395
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_UNCORE_ADDR_OPCODE_MATCH 0x00000396
+
+
+/**
+ Package. See Section 18.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PMC0);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PMC0, Msr);
+ @endcode
+ @{
+**/
+#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.7.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_UNCORE_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_UNCORE_PERFEVTSEL0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR_CTL);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_FIXED_CTR_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_U_PMON_GLOBAL_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_EVNT_SEL);
+ AsmWriteMsr64 (MSR_NEHALEM_U_PMON_EVNT_SEL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_U_PMON_CTR);
+ AsmWriteMsr64 (MSR_NEHALEM_U_PMON_CTR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_W_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_W_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_TIMESTAMP);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_TIMESTAMP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_DSP);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_DSP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ISS);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ISS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MAP);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MAP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MSC_THR);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MSC_THR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_PGT);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_PGT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_PLD);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_PLD, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ZDP);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ZDP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_TIMESTAMP);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_TIMESTAMP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_DSP);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_DSP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ISS);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ISS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MAP);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MAP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MSC_THR);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MSC_THR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_PGT);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_PGT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_PLD);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_PLD, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ZDP);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ZDP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C0_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C0_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C4_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C4_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C2_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C2_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C6_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C6_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C1_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C1_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C5_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C5_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C3_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C3_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_C7_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_C7_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P0);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P1);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P2);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P3);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P4);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P5);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P6);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P6, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P7);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_IPERF0_P7, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P0);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P1);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P2);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_QLX_P3);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_QLX_P3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL1);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL2);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL3);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL4);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR4);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL5);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR5);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL6);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL6, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR6);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR6, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL7);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_EVNT_SEL7, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R0_PMON_CTR7);
+ AsmWriteMsr64 (MSR_NEHALEM_R0_PMON_CTR7, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P8);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P8, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P9);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P9, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P10);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P10, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P11);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P11, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P12);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P12, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P13);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P13, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P14);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P14, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P15);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_IPERF1_P15, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P4);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P5);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P6);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P6, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_QLX_P7);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_QLX_P7, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL8);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL8, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR8);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR8, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL9);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL9, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR9);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR9, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL10);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL10, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR10);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR10, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL11);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL11, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR11);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR11, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL12);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL12, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR12);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR12, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL13);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL13, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR13);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR13, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL14);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL14, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR14);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR14, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL15);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_EVNT_SEL15, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_R1_PMON_CTR15);
+ AsmWriteMsr64 (MSR_NEHALEM_R1_PMON_CTR15, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B0_PMON_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_B0_PMON_MASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S0_PMON_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_S0_PMON_MASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_B1_PMON_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_B1_PMON_MASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_MM_CONFIG);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_MM_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_M0_PMON_ADDR_MASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_S1_PMON_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_S1_PMON_MASK, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_MM_CONFIG);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_MM_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MATCH);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MATCH, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MASK);
+ AsmWriteMsr64 (MSR_NEHALEM_M1_PMON_ADDR_MASK, Msr);
+ @endcode
+**/
+#define MSR_NEHALEM_M1_PMON_ADDR_MASK 0x00000E5E
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/P6Msr.h b/Core/UefiCpuPkg/Include/Register/Msr/P6Msr.h
new file mode 100644
index 0000000000..7ee0b28356
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/P6Msr.h
@@ -0,0 +1,1608 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-19.
+
+**/
+
+#ifndef __P6_MSR_H__
+#define __P6_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_P5_MC_ADDR);
+ AsmWriteMsr64 (MSR_P6_P5_MC_ADDR, Msr);
+ @endcode
+**/
+#define MSR_P6_P5_MC_ADDR 0x00000000
+
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_P5_MC_TYPE);
+ AsmWriteMsr64 (MSR_P6_P5_MC_TYPE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_TSC);
+ AsmWriteMsr64 (MSR_P6_TSC, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_IA32_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_IA32_PLATFORM_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_APIC_BASE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_APIC_BASE);
+ AsmWriteMsr64 (MSR_P6_APIC_BASE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_TEST_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_TEST_CTL);
+ AsmWriteMsr64 (MSR_P6_TEST_CTL, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BIOS_UPDT_TRIG);
+ AsmWriteMsr64 (MSR_P6_BIOS_UPDT_TRIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BBL_CR_D0);
+ AsmWriteMsr64 (MSR_P6_BBL_CR_D0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BIOS_SIGN);
+ AsmWriteMsr64 (MSR_P6_BIOS_SIGN, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_PERFCTR0);
+ AsmWriteMsr64 (MSR_P6_PERFCTR0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRCAP);
+ AsmWriteMsr64 (MSR_P6_MTRRCAP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BBL_CR_DECC);
+ AsmWriteMsr64 (MSR_P6_BBL_CR_DECC, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BBL_CR_TRIG);
+ AsmWriteMsr64 (MSR_P6_BBL_CR_TRIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_BBL_CR_BUSY);
+ AsmWriteMsr64 (MSR_P6_BBL_CR_BUSY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_SYSENTER_CS_MSR);
+ AsmWriteMsr64 (MSR_P6_SYSENTER_CS_MSR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_SYSENTER_ESP_MSR);
+ AsmWriteMsr64 (MSR_P6_SYSENTER_ESP_MSR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_SYSENTER_EIP_MSR);
+ AsmWriteMsr64 (MSR_P6_SYSENTER_EIP_MSR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MCG_CAP);
+ AsmWriteMsr64 (MSR_P6_MCG_CAP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MCG_STATUS);
+ AsmWriteMsr64 (MSR_P6_MCG_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MCG_CTL);
+ AsmWriteMsr64 (MSR_P6_MCG_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_PERFEVTSEL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_P6_PERFEVTSEL0, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_DEBUGCTLMSR_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_DEBUGCTLMSR);
+ AsmWriteMsr64 (MSR_P6_DEBUGCTLMSR, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_LASTBRANCHFROMIP);
+ AsmWriteMsr64 (MSR_P6_LASTBRANCHFROMIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_LASTBRANCHTOIP);
+ AsmWriteMsr64 (MSR_P6_LASTBRANCHTOIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_LASTINTFROMIP);
+ AsmWriteMsr64 (MSR_P6_LASTINTFROMIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_LASTINTTOIP);
+ AsmWriteMsr64 (MSR_P6_LASTINTTOIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRPHYSBASE0);
+ AsmWriteMsr64 (MSR_P6_MTRRPHYSBASE0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRPHYSMASK0);
+ AsmWriteMsr64 (MSR_P6_MTRRPHYSMASK0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX64K_00000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX64K_00000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX16K_80000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX16K_80000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX16K_A0000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX16K_A0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_C0000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_C0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_C8000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_C8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_D0000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_D0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_D8000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_D8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_E0000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_E0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_E8000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_E8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_F0000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_F0000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MTRRFIX4K_F8000);
+ AsmWriteMsr64 (MSR_P6_MTRRFIX4K_F8000, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_MTRRDEFTYPE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_MTRRDEFTYPE);
+ AsmWriteMsr64 (MSR_P6_MTRRDEFTYPE, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MC0_CTL);
+ AsmWriteMsr64 (MSR_P6_MC0_CTL, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_P6_MC_STATUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_P6_MC0_STATUS);
+ AsmWriteMsr64 (MSR_P6_MC0_STATUS, Msr.Uint64);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MC0_ADDR);
+ AsmWriteMsr64 (MSR_P6_MC0_ADDR, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_P6_MC0_MISC);
+ AsmWriteMsr64 (MSR_P6_MC0_MISC, Msr);
+ @endcode
+ @{
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h b/Core/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h
new file mode 100644
index 0000000000..caeb5bb035
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/Pentium4Msr.h
@@ -0,0 +1,2550 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-16.
+
+**/
+
+#ifndef __PENTIUM_4_MSR_H__
+#define __PENTIUM_4_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IA32_MONITOR_FILTER_LINE_SIZE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_FREQUENCY_ID);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_PENTIUM_4_EBC_FREQUENCY_ID_1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_FREQUENCY_ID_1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RAX);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RAX, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RBX);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RBX, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RCX);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RCX, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RDX);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RDX, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RSI);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RSI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RDI);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RDI, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RBP);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RBP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RSP);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RSP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RFLAGS);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RFLAGS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_RIP);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_RIP, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R8);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R8, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R9);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R9, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R10);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R10, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R11);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R11, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R12);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R12, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R13);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R13, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R14);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R14, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MCG_R15);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MCG_R15, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_THERM2_CTL);
+ AsmWriteMsr64 (MSR_PENTIUM_4_THERM2_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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: Precise Event Based Sampling Unavailable (R)
+ /// See Table 35-2. When set, the processor does not support precise
+ /// 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_PENTIUM_4_PLATFORM_BRV_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_PLATFORM_BRV);
+ @endcode
+**/
+#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.10.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LER_FROM_LIP);
+ @endcode
+**/
+#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.10.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LER_TO_LIP);
+ @endcode
+**/
+#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.10.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_DEBUGCTLA);
+ AsmWriteMsr64 (MSR_PENTIUM_4_DEBUGCTLA, Msr);
+ @endcode
+**/
+#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.10.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.9, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_COUNTER0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BPU_COUNTER0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_COUNTER0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MS_COUNTER0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_COUNTER0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_COUNTER0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_COUNTER0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IQ_COUNTER0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_CCCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BPU_CCCR0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_CCCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MS_CCCR0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_CCCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_CCCR0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_CCCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IQ_CCCR0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BSU_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BSU_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_BSU_ESCR0 0x000003A0
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BSU_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BSU_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_BSU_ESCR1 0x000003A1
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FSB_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FSB_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FSB_ESCR0 0x000003A2
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FSB_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FSB_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FSB_ESCR1 0x000003A3
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FIRM_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FIRM_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FIRM_ESCR0 0x000003A4
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FIRM_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FIRM_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FIRM_ESCR1 0x000003A5
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FLAME_ESCR0 0x000003A6
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_FLAME_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_FLAME_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_FLAME_ESCR1 0x000003A7
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_DAC_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_DAC_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_DAC_ESCR0 0x000003A8
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_DAC_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_DAC_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_DAC_ESCR1 0x000003A9
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MOB_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MOB_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_MOB_ESCR0 0x000003AA
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MOB_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MOB_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_MOB_ESCR1 0x000003AB
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_PMH_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_PMH_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_PMH_ESCR0 0x000003AC
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_PMH_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_PMH_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_PMH_ESCR1 0x000003AD
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_SAAT_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_SAAT_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_SAAT_ESCR0 0x000003AE
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_SAAT_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_SAAT_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_SAAT_ESCR1 0x000003AF
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_U2L_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_U2L_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_U2L_ESCR0 0x000003B0
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_U2L_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_U2L_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_U2L_ESCR1 0x000003B1
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BPU_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_BPU_ESCR0 0x000003B2
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_BPU_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_BPU_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_BPU_ESCR1 0x000003B3
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IS_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IS_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IS_ESCR0 0x000003B4
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IS_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IS_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IS_ESCR1 0x000003B5
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_ITLB_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_ITLB_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_ITLB_ESCR0 0x000003B6
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_ITLB_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_ITLB_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_ITLB_ESCR1 0x000003B7
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_CRU_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_CRU_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_CRU_ESCR0 0x000003B8
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_CRU_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_CRU_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_CRU_ESCR1 0x000003B9
+
+
+/**
+ 0, 1, 2. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IQ_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IQ_ESCR0 0x000003BA
+
+
+/**
+ 0, 1, 2. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IQ_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IQ_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IQ_ESCR1 0x000003BB
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_RAT_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_RAT_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_RAT_ESCR0 0x000003BC
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_RAT_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_RAT_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_RAT_ESCR1 0x000003BD
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_SSU_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_SSU_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_SSU_ESCR0 0x000003BE
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MS_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_MS_ESCR0 0x000003C0
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_MS_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_MS_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_MS_ESCR1 0x000003C1
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_TBPU_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_TBPU_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_TBPU_ESCR0 0x000003C2
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_TBPU_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_TBPU_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_TBPU_ESCR1 0x000003C3
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_TC_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_TC_ESCR0 0x000003C4
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_TC_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_TC_ESCR1 0x000003C5
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IX_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IX_ESCR0, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IX_ESCR0 0x000003C8
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IX_ESCR1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IX_ESCR1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IX_ESCR1 0x000003C9
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. See Section 18.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_ALF_ESCR0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_ALF_ESCR0, Msr);
+ @endcode
+ @{
+**/
+#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.12.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_TC_PRECISE_EVENT);
+ AsmWriteMsr64 (MSR_PENTIUM_4_TC_PRECISE_EVENT, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_TC_PRECISE_EVENT 0x000003F0
+
+
+/**
+ 0, 1, 2, 3, 4, 6. Shared. Precise Event-Based Sampling (PEBS) (R/W)
+ Controls the enabling of precise 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-26.
+ ///
+ 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.13.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.13.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-26.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_PEBS_MATRIX_VERT);
+ AsmWriteMsr64 (MSR_PENTIUM_4_PEBS_MATRIX_VERT, Msr);
+ @endcode
+**/
+#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.9, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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.9, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_PENTIUM_4_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.17, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_BUSQ0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_BUSQ0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_BUSQ1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_BUSQ1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IFSB_BUSQ1 0x000107CD
+
+
+/**
+ 3, 4. Shared. IFSB SNPQ Event Control and Counter Register (R/W) See
+ Section 18.17, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_SNPQ0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_SNPQ0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_SNPQ1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_SNPQ1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IFSB_SNPQ1 0x000107CF
+
+
+/**
+ 3, 4. Shared. EFSB DRDY Event Control and Counter Register (R/W) See
+ Section 18.17, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EFSB_DRDY0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EFSB_DRDY0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EFSB_DRDY1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EFSB_DRDY1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_EFSB_DRDY1 0x000107D1
+
+
+/**
+ 3, 4. Shared. IFSB Latency Event Control Register (R/W) See Section 18.17,
+ "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_CTL6);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_CTL6, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IFSB_CTL6 0x000107D2
+
+
+/**
+ 3, 4. Shared. IFSB Latency Event Counter Register (R/W) See Section 18.17,
+ "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_IFSB_CNTR7);
+ AsmWriteMsr64 (MSR_PENTIUM_4_IFSB_CNTR7, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_IFSB_CNTR7 0x000107D3
+
+
+/**
+ 6. Shared. GBUSQ Event Control and Counter Register (R/W) See Section 18.17,
+ "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL0);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL1);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL1, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_EMON_L3_CTR_CTL1 0x000107CD
+
+
+/**
+ 6. Shared. GSNPQ Event Control and Counter Register (R/W) See Section
+ 18.17, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL2);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL3);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL3, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_EMON_L3_CTR_CTL3 0x000107CF
+
+
+/**
+ 6. Shared. FSB Event Control and Counter Register (R/W) See Section 18.17,
+ "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL4);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL4, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL5);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL5, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL6);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL6, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL7);
+ AsmWriteMsr64 (MSR_PENTIUM_4_EMON_L3_CTR_CTL7, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_4_EMON_L3_CTR_CTL7 0x000107D3
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h
new file mode 100644
index 0000000000..324fc9b88c
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/PentiumMMsr.h
@@ -0,0 +1,643 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-18.
+
+**/
+
+#ifndef __PENTIUM_M_MSR_H__
+#define __PENTIUM_M_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_P5_MC_ADDR);
+ AsmWriteMsr64 (MSR_PENTIUM_M_P5_MC_ADDR, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_M_P5_MC_ADDR 0x00000000
+
+
+/**
+ See Section 35.20, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_P5_MC_TYPE);
+ AsmWriteMsr64 (MSR_PENTIUM_M_P5_MC_TYPE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.12, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_LASTBRANCH_0);
+ AsmWriteMsr64 (MSR_PENTIUM_M_LASTBRANCH_0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_BBL_CR_CTL);
+ AsmWriteMsr64 (MSR_PENTIUM_M_BBL_CR_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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] Precise Event Based Sampling Unavailable (RO) 1 = Processor
+ /// does not support precise 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.12, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_PENTIUM_M_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.12,
+ "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_DEBUGCTLB);
+ AsmWriteMsr64 (MSR_PENTIUM_M_DEBUGCTLB, Msr);
+ @endcode
+**/
+#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.12, "Last Branch, Interrupt, and Exception Recording
+ (Pentium M Processors)" and Section 17.13.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_LER_TO_LIP);
+ @endcode
+**/
+#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.12, "Last Branch, Interrupt, and Exception Recording (Pentium M
+ Processors)" and Section 17.13.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_CTL);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC4_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_STATUS);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC4_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC4_ADDR);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC4_ADDR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_CTL);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC3_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_STATUS);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC3_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_M_MC3_ADDR);
+ AsmWriteMsr64 (MSR_PENTIUM_M_MC3_ADDR, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_M_MC3_ADDR 0x00000412
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h
new file mode 100644
index 0000000000..a8916b4a44
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/PentiumMsr.h
@@ -0,0 +1,121 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-20.
+
+**/
+
+#ifndef __PENTIUM_MSR_H__
+#define __PENTIUM_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_P5_MC_ADDR);
+ AsmWriteMsr64 (MSR_PENTIUM_P5_MC_ADDR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_P5_MC_TYPE);
+ AsmWriteMsr64 (MSR_PENTIUM_P5_MC_TYPE, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_P5_MC_TYPE 0x00000001
+
+
+/**
+ See Section 17.14, "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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_TSC);
+ AsmWriteMsr64 (MSR_PENTIUM_TSC, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_TSC 0x00000010
+
+
+/**
+ See Section 18.20.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_CESR);
+ AsmWriteMsr64 (MSR_PENTIUM_CESR, Msr);
+ @endcode
+**/
+#define MSR_PENTIUM_CESR 0x00000011
+
+
+/**
+ Section 18.20.3, "Events Counted.".
+
+ @param ECX MSR_PENTIUM_CTRn
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_PENTIUM_CTR0);
+ AsmWriteMsr64 (MSR_PENTIUM_CTR0, Msr);
+ @endcode
+ @{
+**/
+#define MSR_PENTIUM_CTR0 0x00000012
+#define MSR_PENTIUM_CTR1 0x00000013
+/// @}
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h
new file mode 100644
index 0000000000..c41e45b414
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/SandyBridgeMsr.h
@@ -0,0 +1,4703 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-8.
+
+**/
+
+#ifndef __SANDY_BRIDGE_MSR_H__
+#define __SANDY_BRIDGE_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SANDY_BRIDGE_SMI_COUNT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_SMI_COUNT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERFEVTSEL4, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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. Precise 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_OFFCORE_RSP_1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MISC_PWR_MGMT);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MISC_PWR_MGMT, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_MISC_PWR_MGMT 0x000001AA
+
+
+/**
+ Thread. Last Branch Record Filtering Select Register (R/W) See Section
+ 17.6.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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LER_TO_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_POWER_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_POWER_CTL, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_POWER_CTL 0x000001FC
+
+
+/**
+ Package. Always 0 (CMCI not supported).
+
+ @param ECX MSR_SANDY_BRIDGE_MC4_CTL2 (0x00000284)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC4_CTL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC4_CTL2, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_MC4_CTL2 0x00000284
+
+
+/**
+ See Table 35-2. See Section 18.4.2, "Global Counter Control Facilities.".
+
+ @param ECX MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS, Msr.Uint64);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+/**
+ MSR information returned for MSR index
+ #MSR_SANDY_BRIDGE_IA32_PERF_GLOBAL_STAUS
+**/
+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_STAUS_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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.7.1.1, "Precise 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.7.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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C3_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C7_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C3_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_CORE_C7_RESIDENCY 0x000003FE
+
+
+/**
+ Core. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_SANDY_BRIDGE_MC4_CTL (0x00000410)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_SANDY_BRIDGE_MC4_CTL_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_SANDY_BRIDGE_MC4_CTL_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_SANDY_BRIDGE_MC4_CTL_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC4_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC4_CTL, Msr.Uint64);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_MC4_CTL 0x00000410
+
+/**
+ MSR information returned for MSR index #MSR_SANDY_BRIDGE_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_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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_IA32_VMX_EPT_VPID_ENUM);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_C2_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_INFO);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PKG_POWER_INFO, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP0_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_ENERGY_STATUS);
+ @endcode
+**/
+#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.6.1, "LBR Stack.".
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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] 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_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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SANDY_BRIDGE_UNC_CBO_CONFIG_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_CONFIG);
+ @endcode
+**/
+#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] 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_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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFCTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_ARB_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP0_POLICY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP0_POLICY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP1_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PP1_POLICY);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PP1_POLICY, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_PP1_POLICY 0x00000642
+
+
+/**
+ Package. Uncore C-Box 0, counter 0 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0 (0x00000700)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL0 0x00000700
+
+
+/**
+ Package. Uncore C-Box 0, counter 1 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1 (0x00000701)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFEVTSEL1 0x00000701
+
+
+/**
+ Package. Uncore C-Box 0, performance counter 0.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0 (0x00000706)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR0 0x00000706
+
+
+/**
+ Package. Uncore C-Box 0, performance counter 1.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1 (0x00000707)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_0_PERFCTR1 0x00000707
+
+
+/**
+ Package. Uncore C-Box 1, counter 0 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0 (0x00000710)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL0 0x00000710
+
+
+/**
+ Package. Uncore C-Box 1, counter 1 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1 (0x00000711)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFEVTSEL1 0x00000711
+
+
+/**
+ Package. Uncore C-Box 1, performance counter 0.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0 (0x00000716)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR0 0x00000716
+
+
+/**
+ Package. Uncore C-Box 1, performance counter 1.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1 (0x00000717)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_1_PERFCTR1 0x00000717
+
+
+/**
+ Package. Uncore C-Box 2, counter 0 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0 (0x00000720)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL0 0x00000720
+
+
+/**
+ Package. Uncore C-Box 2, counter 1 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1 (0x00000721)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFEVTSEL1 0x00000721
+
+
+/**
+ Package. Uncore C-Box 2, performance counter 0.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0 (0x00000726)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR0 0x00000726
+
+
+/**
+ Package. Uncore C-Box 2, performance counter 1.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1 (0x00000727)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_2_PERFCTR1 0x00000727
+
+
+/**
+ Package. Uncore C-Box 3, counter 0 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0 (0x00000730)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL0 0x00000730
+
+
+/**
+ Package. Uncore C-Box 3, counter 1 event select MSR.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1 (0x00000731)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFEVTSEL1 0x00000731
+
+
+/**
+ Package. Uncore C-Box 3, performance counter 0.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0 (0x00000736)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR0 0x00000736
+
+
+/**
+ Package. Uncore C-Box 3, performance counter 1.
+
+ @param ECX MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1 (0x00000737)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_UNC_CBO_3_PERFCTR1 0x00000737
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-9.
+ ///
+ 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. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_SANDY_BRIDGE_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC5_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC5_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SANDY_BRIDGE_MC5_CTL 0x00000414
+#define MSR_SANDY_BRIDGE_MC6_CTL 0x00000418
+#define MSR_SANDY_BRIDGE_MC7_CTL 0x0000041C
+#define MSR_SANDY_BRIDGE_MC8_CTL 0x00000420
+#define MSR_SANDY_BRIDGE_MC9_CTL 0x00000424
+#define MSR_SANDY_BRIDGE_MC10_CTL 0x00000428
+#define MSR_SANDY_BRIDGE_MC11_CTL 0x0000042C
+#define MSR_SANDY_BRIDGE_MC12_CTL 0x00000430
+#define MSR_SANDY_BRIDGE_MC13_CTL 0x00000434
+#define MSR_SANDY_BRIDGE_MC14_CTL 0x00000438
+#define MSR_SANDY_BRIDGE_MC15_CTL 0x0000043C
+#define MSR_SANDY_BRIDGE_MC16_CTL 0x00000440
+#define MSR_SANDY_BRIDGE_MC17_CTL 0x00000444
+#define MSR_SANDY_BRIDGE_MC18_CTL 0x00000448
+#define MSR_SANDY_BRIDGE_MC19_CTL 0x0000044C
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS," and Chapter 16.
+
+ @param ECX MSR_SANDY_BRIDGE_MCi_STATUS
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC5_STATUS);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC5_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SANDY_BRIDGE_MC5_STATUS 0x00000415
+#define MSR_SANDY_BRIDGE_MC6_STATUS 0x00000419
+#define MSR_SANDY_BRIDGE_MC7_STATUS 0x0000041D
+#define MSR_SANDY_BRIDGE_MC8_STATUS 0x00000421
+#define MSR_SANDY_BRIDGE_MC9_STATUS 0x00000425
+#define MSR_SANDY_BRIDGE_MC10_STATUS 0x00000429
+#define MSR_SANDY_BRIDGE_MC11_STATUS 0x0000042D
+#define MSR_SANDY_BRIDGE_MC12_STATUS 0x00000431
+#define MSR_SANDY_BRIDGE_MC13_STATUS 0x00000435
+#define MSR_SANDY_BRIDGE_MC14_STATUS 0x00000439
+#define MSR_SANDY_BRIDGE_MC15_STATUS 0x0000043D
+#define MSR_SANDY_BRIDGE_MC16_STATUS 0x00000441
+#define MSR_SANDY_BRIDGE_MC17_STATUS 0x00000445
+#define MSR_SANDY_BRIDGE_MC18_STATUS 0x00000449
+#define MSR_SANDY_BRIDGE_MC19_STATUS 0x0000044D
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs.".
+
+ @param ECX MSR_SANDY_BRIDGE_MCi_ADDR
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC5_ADDR);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC5_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SANDY_BRIDGE_MC5_ADDR 0x00000416
+#define MSR_SANDY_BRIDGE_MC6_ADDR 0x0000041A
+#define MSR_SANDY_BRIDGE_MC7_ADDR 0x0000041E
+#define MSR_SANDY_BRIDGE_MC8_ADDR 0x00000422
+#define MSR_SANDY_BRIDGE_MC9_ADDR 0x00000426
+#define MSR_SANDY_BRIDGE_MC10_ADDR 0x0000042A
+#define MSR_SANDY_BRIDGE_MC11_ADDR 0x0000042E
+#define MSR_SANDY_BRIDGE_MC12_ADDR 0x00000432
+#define MSR_SANDY_BRIDGE_MC13_ADDR 0x00000436
+#define MSR_SANDY_BRIDGE_MC14_ADDR 0x0000043A
+#define MSR_SANDY_BRIDGE_MC15_ADDR 0x0000043E
+#define MSR_SANDY_BRIDGE_MC16_ADDR 0x00000442
+#define MSR_SANDY_BRIDGE_MC17_ADDR 0x00000446
+#define MSR_SANDY_BRIDGE_MC18_ADDR 0x0000044A
+#define MSR_SANDY_BRIDGE_MC19_ADDR 0x0000044E
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_SANDY_BRIDGE_MCi_MISC
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_MC5_MISC);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_MC5_MISC, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SANDY_BRIDGE_MC5_MISC 0x00000417
+#define MSR_SANDY_BRIDGE_MC6_MISC 0x0000041B
+#define MSR_SANDY_BRIDGE_MC7_MISC 0x0000041F
+#define MSR_SANDY_BRIDGE_MC8_MISC 0x00000423
+#define MSR_SANDY_BRIDGE_MC9_MISC 0x00000427
+#define MSR_SANDY_BRIDGE_MC10_MISC 0x0000042B
+#define MSR_SANDY_BRIDGE_MC11_MISC 0x0000042F
+#define MSR_SANDY_BRIDGE_MC12_MISC 0x00000433
+#define MSR_SANDY_BRIDGE_MC13_MISC 0x00000437
+#define MSR_SANDY_BRIDGE_MC14_MISC 0x0000043B
+#define MSR_SANDY_BRIDGE_MC15_MISC 0x0000043F
+#define MSR_SANDY_BRIDGE_MC16_MISC 0x00000443
+#define MSR_SANDY_BRIDGE_MC17_MISC 0x00000447
+#define MSR_SANDY_BRIDGE_MC18_MISC 0x0000044B
+#define MSR_SANDY_BRIDGE_MC19_MISC 0x0000044F
+/// @}
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_INFO);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_DRAM_POWER_INFO, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_UCLK_FIXED_CTR, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_U_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_PCU_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C0_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C1_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C2_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C3_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C4_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C5_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C6_PMON_CTR3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_CTL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_EVNTSEL3, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_BOX_FILTER, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR0);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR1);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR2);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR2, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR3);
+ AsmWriteMsr64 (MSR_SANDY_BRIDGE_C7_PMON_CTR3, Msr);
+ @endcode
+**/
+#define MSR_SANDY_BRIDGE_C7_PMON_CTR3 0x00000DF9
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h
new file mode 100644
index 0000000000..4272375ea5
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/SilvermontMsr.h
@@ -0,0 +1,1468 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-4.
+
+**/
+
+#ifndef __SILVERMONT_MSR_H__
+#define __SILVERMONT_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_PLATFORM_ID_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PLATFORM_ID);
+ @endcode
+**/
+#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;
+
+
+/**
+ Shared. Processor Hard Power-On Configuration (R/W) Enables and disables
+ processor features; (R) indicates current processor configuration.
+
+ @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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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: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_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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_SMI_COUNT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_SMI_COUNT);
+ @endcode
+**/
+#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. Last Branch Record n From IP (R/W) One of eight pairs of last branch
+ record registers on the last branch record stack. This part of the stack
+ contains pointers to the source instruction for one of the last eight
+ branches, exceptions, or interrupts taken by the processor. See also: -
+ Last Branch Record Stack TOS at 1C9H - Section 17.12, "Last Branch,
+ Interrupt, and Exception Recording (Pentium M Processors).".
+
+ @param ECX MSR_SILVERMONT_LASTBRANCH_n_FROM_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_0_FROM_IP);
+ AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_0_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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. This part of the stack
+ contains pointers to the destination instruction for one of the last eight
+ branches, exceptions, or interrupts taken by the processor.
+
+ @param ECX MSR_SILVERMONT_LASTBRANCH_n_TO_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_0_TO_IP);
+ AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_0_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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
+/// @}
+
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_FSB_FREQ_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_FSB_FREQ);
+ @endcode
+**/
+#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;
+
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ Shared.
+
+ @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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_FEATURE_CONFIG_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_FEATURE_CONFIG);
+ AsmWriteMsr64 (MSR_SILVERMONT_FEATURE_CONFIG, Msr.Uint64);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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] Shared. Automatic Thermal Control Circuit Enable (R/W) See
+ /// Table 35-2.
+ ///
+ 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. Precise Event Based Sampling Unavailable (RO) See Table
+ /// 35-2.
+ ///
+ UINT32 PEBS:1;
+ UINT32 Reserved4:3;
+ ///
+ /// [Bit 16] Shared. 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] Shared. 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] Shared. 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_TEMPERATURE_TARGET_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_TEMPERATURE_TARGET);
+ AsmWriteMsr64 (MSR_SILVERMONT_TEMPERATURE_TARGET, Msr.Uint64);
+ @endcode
+**/
+#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;
+
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_OFFCORE_RSP_0);
+ AsmWriteMsr64 (MSR_SILVERMONT_OFFCORE_RSP_0, Msr);
+ @endcode
+**/
+#define MSR_SILVERMONT_OFFCORE_RSP_0 0x000001A6
+
+
+/**
+ Shared. 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_OFFCORE_RSP_1);
+ AsmWriteMsr64 (MSR_SILVERMONT_OFFCORE_RSP_1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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 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_SILVERMONT_LASTBRANCH_TOS (0x000001C9)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_SILVERMONT_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_LER_TO_LIP);
+ @endcode
+**/
+#define MSR_SILVERMONT_LER_TO_LIP 0x000001DE
+
+
+/**
+ Core. See Table 35-2. See Section 18.4.2, "Global Counter Control
+ Facilities.".
+
+ @param ECX MSR_SILVERMONT_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_SILVERMONT_IA32_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_SILVERMONT_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+
+/**
+ Core. See Table 35-2. See Section 18.4.4, "Precise 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_PEBS_ENABLE_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_SILVERMONT_PEBS_ENABLE, Msr.Uint64);
+ @endcode
+**/
+#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 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_PKG_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_SILVERMONT_PKG_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_CORE_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_SILVERMONT_CORE_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#define MSR_SILVERMONT_CORE_C6_RESIDENCY 0x000003FD
+
+
+/**
+ Core. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_SILVERMONT_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_MC3_CTL);
+ AsmWriteMsr64 (MSR_SILVERMONT_MC3_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SILVERMONT_MC3_CTL 0x0000040C
+#define MSR_SILVERMONT_MC4_CTL 0x00000410
+#define MSR_SILVERMONT_MC5_CTL 0x00000414
+/// @}
+
+
+/**
+ Core. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_SILVERMONT_MCi_STATUS
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_MC3_STATUS);
+ AsmWriteMsr64 (MSR_SILVERMONT_MC3_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SILVERMONT_MC3_STATUS 0x0000040D
+#define MSR_SILVERMONT_MC4_STATUS 0x00000411
+#define MSR_SILVERMONT_MC5_STATUS 0x00000415
+/// @}
+
+
+/**
+ Core. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs." The MSR_MCi_ADDR register
+ is either not implemented or contains no address if the ADDRV flag in the
+ MSR_MCi_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_SILVERMONT_MCi_ADDR
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_MC3_ADDR);
+ AsmWriteMsr64 (MSR_SILVERMONT_MC3_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_SILVERMONT_MC3_ADDR 0x0000040E
+#define MSR_SILVERMONT_MC4_ADDR 0x00000412
+#define MSR_SILVERMONT_MC5_ADDR 0x00000416
+/// @}
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_IA32_VMX_EPT_VPID_ENUM);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_IA32_VMX_FMFUNC);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_CORE_C1_RESIDENCY);
+ AsmWriteMsr64 (MSR_SILVERMONT_CORE_C1_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_RAPL_POWER_UNIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-7.
+ ///
+ 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-7.
+
+ @param ECX MSR_SILVERMONT_PKG_ENERGY_STATUS (0x00000611)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_PKG_ENERGY_STATUS);
+ @endcode
+**/
+#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-7.
+
+ @param ECX MSR_SILVERMONT_PP0_ENERGY_STATUS (0x00000639)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_PP0_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG);
+ AsmWriteMsr64 (MSR_SILVERMONT_CC6_DEMOTION_POLICY_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG);
+ AsmWriteMsr64 (MSR_SILVERMONT_MC6_DEMOTION_POLICY_CONFIG, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SILVERMONT_MC6_RESIDENCY_COUNTER);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SILVERMONT_PKG_POWER_INFO_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_PKG_POWER_INFO);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-7.
+ ///
+ 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/Core/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h
new file mode 100644
index 0000000000..34868f9a27
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/SkylakeMsr.h
@@ -0,0 +1,1008 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-14.
+
+**/
+
+#ifndef __SKYLAKE_MSR_H__
+#define __SKYLAKE_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SKYLAKE_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_SGXOWNER0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_SGXOWNER1);
+ @endcode
+**/
+#define MSR_SKYLAKE_SGXOWNER1 0x00000301
+
+
+/**
+ See Table 35-2. See Section 18.2.2.3, "Full-Width Writes to Performance
+ Counter Registers.".
+
+ @param ECX MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS, Msr.Uint64);
+ @endcode
+**/
+#define MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+/**
+ MSR information returned for MSR index #MSR_SKYLAKE_IA32_PERF_GLOBAL_STAUS
+**/
+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_STAUS_REGISTER;
+
+
+/**
+ See Table 35-2. See Section 18.2.2.3, "Full-Width Writes to Performance
+ Counter Registers.".
+
+ @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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.2.3, "Full-Width Writes to Performance
+ Counter Registers.".
+
+ @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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SKYLAKE_PEBS_FRONTEND_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PEBS_FRONTEND);
+ AsmWriteMsr64 (MSR_SKYLAKE_PEBS_FRONTEND, Msr.Uint64);
+ @endcode
+**/
+#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;
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_SKYLAKE_PLATFORM_ENERGY_COUNTER);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_PPERF);
+ @endcode
+**/
+#define MSR_SKYLAKE_PPERF 0x0000064E
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_CORE_HDC_RESIDENCY);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_PKG_HDC_SHALLOW_RESIDENCY);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_PKG_HDC_DEEP_RESIDENCY);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_WEIGHTED_CORE_C0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_ANY_CORE_C0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_ANY_GFXE_C0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_CORE_GFXE_OVERLAP_C0);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.9.
+
+ @param ECX MSR_SKYLAKE_LASTBRANCH_n_FROM_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_16_FROM_IP);
+ AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_16_FROM_IP, Msr);
+ @endcode
+ @{
+**/
+#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
+/// @}
+
+/**
+ 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.9.
+
+ @param ECX MSR_SKYLAKE_LASTBRANCH_n_TO_IP
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_LASTBRANCH_16_TO_IP);
+ AsmWriteMsr64 (MSR_SKYLAKE_LASTBRANCH_16_TO_IP, Msr);
+ @endcode
+ @{
+**/
+#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.6.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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_SKYLAKE_LBR_INFO_0);
+ AsmWriteMsr64 (MSR_SKYLAKE_LBR_INFO_0, Msr);
+ @endcode
+ @{
+**/
+#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
+/// @}
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h b/Core/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h
new file mode 100644
index 0000000000..a4c6ba0845
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/Xeon5600Msr.h
@@ -0,0 +1,182 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-6.
+
+**/
+
+#ifndef __XEON_5600_MSR_H__
+#define __XEON_5600_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_5600_OFFCORE_RSP_1);
+ AsmWriteMsr64 (MSR_XEON_5600_OFFCORE_RSP_1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_5600_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_5600_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_5600_IA32_ENERGY_PERF_BIAS);
+ AsmWriteMsr64 (MSR_XEON_5600_IA32_ENERGY_PERF_BIAS, Msr);
+ @endcode
+**/
+#define MSR_XEON_5600_IA32_ENERGY_PERF_BIAS 0x000001B0
+
+#endif
diff --git a/Core/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h
new file mode 100644
index 0000000000..43a35f2a8e
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/XeonDMsr.h
@@ -0,0 +1,1430 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-13.
+
+**/
+
+#ifndef __XEON_D_MSR_H__
+#define __XEON_D_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-21.
+ ///
+ UINT32 LockOut:1;
+ ///
+ /// [Bit 1] Enable_PPIN (R/W) See Table 35-21.
+ ///
+ 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-21.
+
+ @param ECX MSR_XEON_D_PPIN (0x0000004F)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_PPIN);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-21.
+ ///
+ UINT32 MaximumNonTurboRatio:8;
+ UINT32 Reserved2:7;
+ ///
+ /// [Bit 23] Package. PPIN_CAP (R/O) See Table 35-21.
+ ///
+ UINT32 PPIN_CAP:1;
+ UINT32 Reserved3:4;
+ ///
+ /// [Bit 28] Package. Programmable Ratio Limit for Turbo Mode (R/O) See
+ /// Table 35-21.
+ ///
+ UINT32 RatioLimit:1;
+ ///
+ /// [Bit 29] Package. Programmable TDP Limit for Turbo Mode (R/O) See
+ /// Table 35-21.
+ ///
+ UINT32 TDPLimit:1;
+ ///
+ /// [Bit 30] Package. Programmable TJ OFFSET (R/O) See Table 35-21.
+ ///
+ UINT32 TJOFFSET:1;
+ UINT32 Reserved4:1;
+ UINT32 Reserved5:8;
+ ///
+ /// [Bits 47:40] Package. Maximum Efficiency Ratio (R/O) See Table 35-21.
+ ///
+ 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. <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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_IA32_MCG_CAP_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_IA32_MCG_CAP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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-21.
+ ///
+ UINT32 TemperatureTarget:8;
+ ///
+ /// [Bits 27:24] TCC Activation Offset (R/W) See Table 35-21.
+ ///
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_TURBO_RATIO_LIMIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_TURBO_RATIO_LIMIT1_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT1);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_RAPL_POWER_UNIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_XEON_D_DRAM_POWER_LIMIT, Msr);
+ @endcode
+**/
+#define MSR_XEON_D_DRAM_POWER_LIMIT 0x00000618
+
+
+/**
+ Package. DRAM Energy Status (R/O) See Section 14.9.5, "DRAM RAPL Domain.".
+
+ @param ECX MSR_XEON_D_DRAM_ENERGY_STATUS (0x00000619)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#define MSR_XEON_D_DRAM_ENERGY_STATUS 0x00000619
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_DRAM_POWER_INFO);
+ AsmWriteMsr64 (MSR_XEON_D_DRAM_POWER_INFO, Msr);
+ @endcode
+**/
+#define MSR_XEON_D_DRAM_POWER_INFO 0x0000061C
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.PQM[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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_TURBO_RATIO_LIMIT3_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_TURBO_RATIO_LIMIT3);
+ @endcode
+**/
+#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. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ * Bank MC5 reports MC error from the Intel QPI 0 module.
+ * Bank MC6 reports MC error from the integrated I/O module.
+ * Bank MC7 reports MC error from the home agent HA 0.
+ * Bank MC8 reports MC error from the home agent HA 1.
+ * Banks MC9 through MC16 report MC error from each channel of the integrated
+ memory controllers.
+ * Bank MC17 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo0, CBo3, CBo6, CBo9, CBo12, CBo15.
+ * Bank MC18 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo1, CBo4, CBo7, CBo10, CBo13, CBo16.
+ * Bank MC19 reports MC error from the following pair of CBo/L3 Slices
+ (if the pair is present): CBo2, CBo5, CBo8, CBo11, CBo14, CBo17.
+ * Bank MC20 reports MC error from the Intel QPI 1 module.
+ * Bank MC21 reports MC error from the Intel QPI 2 module.
+
+ @param ECX MSR_XEON_D_MCi_CTL
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_MC5_CTL);
+ AsmWriteMsr64 (MSR_XEON_D_MC5_CTL, Msr);
+ @endcode
+ @{
+**/
+#define MSR_XEON_D_MC5_CTL 0x00000414
+#define MSR_XEON_D_MC6_CTL 0x00000418
+#define MSR_XEON_D_MC7_CTL 0x0000041C
+#define MSR_XEON_D_MC8_CTL 0x00000420
+#define MSR_XEON_D_MC9_CTL 0x00000424
+#define MSR_XEON_D_MC10_CTL 0x00000428
+#define MSR_XEON_D_MC11_CTL 0x0000042C
+#define MSR_XEON_D_MC12_CTL 0x00000430
+#define MSR_XEON_D_MC13_CTL 0x00000434
+#define MSR_XEON_D_MC14_CTL 0x00000438
+#define MSR_XEON_D_MC15_CTL 0x0000043C
+#define MSR_XEON_D_MC16_CTL 0x00000440
+#define MSR_XEON_D_MC17_CTL 0x00000444
+#define MSR_XEON_D_MC18_CTL 0x00000448
+#define MSR_XEON_D_MC19_CTL 0x0000044C
+#define MSR_XEON_D_MC20_CTL 0x00000450
+#define MSR_XEON_D_MC21_CTL 0x00000454
+/// @}
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_XEON_D_MCi_STATUS
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_MC6_STATUS);
+ AsmWriteMsr64 (MSR_XEON_D_MC6_STATUS, Msr);
+ @endcode
+ @{
+**/
+#define MSR_XEON_D_MC5_STATUS 0x00000415
+#define MSR_XEON_D_MC6_STATUS 0x00000419
+#define MSR_XEON_D_MC7_STATUS 0x0000041D
+#define MSR_XEON_D_MC8_STATUS 0x00000421
+#define MSR_XEON_D_MC9_STATUS 0x00000425
+#define MSR_XEON_D_MC10_STATUS 0x00000429
+#define MSR_XEON_D_MC11_STATUS 0x0000042D
+#define MSR_XEON_D_MC12_STATUS 0x00000431
+#define MSR_XEON_D_MC13_STATUS 0x00000435
+#define MSR_XEON_D_MC14_STATUS 0x00000439
+#define MSR_XEON_D_MC15_STATUS 0x0000043D
+#define MSR_XEON_D_MC16_STATUS 0x00000441
+#define MSR_XEON_D_MC17_STATUS 0x00000445
+#define MSR_XEON_D_MC18_STATUS 0x00000449
+#define MSR_XEON_D_MC19_STATUS 0x0000044D
+#define MSR_XEON_D_MC20_STATUS 0x00000451
+#define MSR_XEON_D_MC21_STATUS 0x00000455
+/// @}
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_XEON_D_MCi_ADDR
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_MC6_ADDR);
+ AsmWriteMsr64 (MSR_XEON_D_MC6_ADDR, Msr);
+ @endcode
+ @{
+**/
+#define MSR_XEON_D_MC5_ADDR 0x00000416
+#define MSR_XEON_D_MC6_ADDR 0x0000041A
+#define MSR_XEON_D_MC7_ADDR 0x0000041E
+#define MSR_XEON_D_MC8_ADDR 0x00000422
+#define MSR_XEON_D_MC9_ADDR 0x00000426
+#define MSR_XEON_D_MC10_ADDR 0x0000042A
+#define MSR_XEON_D_MC11_ADDR 0x0000042E
+#define MSR_XEON_D_MC12_ADDR 0x00000432
+#define MSR_XEON_D_MC13_ADDR 0x00000436
+#define MSR_XEON_D_MC14_ADDR 0x0000043A
+#define MSR_XEON_D_MC15_ADDR 0x0000043E
+#define MSR_XEON_D_MC16_ADDR 0x00000442
+#define MSR_XEON_D_MC17_ADDR 0x00000446
+#define MSR_XEON_D_MC18_ADDR 0x0000044A
+#define MSR_XEON_D_MC19_ADDR 0x0000044E
+#define MSR_XEON_D_MC20_ADDR 0x00000452
+#define MSR_XEON_D_MC21_ADDR 0x00000456
+/// @}
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs." through Section
+ 15.3.2.4, "IA32_MCi_MISC MSRs.".
+
+ @param ECX MSR_XEON_D_MCi_MISC
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_D_MC6_MISC);
+ AsmWriteMsr64 (MSR_XEON_D_MC6_MISC, Msr);
+ @endcode
+ @{
+**/
+#define MSR_XEON_D_MC5_MISC 0x00000417
+#define MSR_XEON_D_MC6_MISC 0x0000041B
+#define MSR_XEON_D_MC7_MISC 0x0000041F
+#define MSR_XEON_D_MC8_MISC 0x00000423
+#define MSR_XEON_D_MC9_MISC 0x00000427
+#define MSR_XEON_D_MC10_MISC 0x0000042B
+#define MSR_XEON_D_MC11_MISC 0x0000042F
+#define MSR_XEON_D_MC12_MISC 0x00000433
+#define MSR_XEON_D_MC13_MISC 0x00000437
+#define MSR_XEON_D_MC14_MISC 0x0000043B
+#define MSR_XEON_D_MC15_MISC 0x0000043F
+#define MSR_XEON_D_MC16_MISC 0x00000443
+#define MSR_XEON_D_MC17_MISC 0x00000447
+#define MSR_XEON_D_MC18_MISC 0x0000044B
+#define MSR_XEON_D_MC19_MISC 0x0000044F
+#define MSR_XEON_D_MC20_MISC 0x00000453
+#define MSR_XEON_D_MC21_MISC 0x00000457
+/// @}
+
+
+/**
+ 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_XEON_D_PKG_C8_RESIDENCY (0x00000630)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C8_RESIDENCY_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C8_RESIDENCY_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_PKG_C8_RESIDENCY_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PKG_C8_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_D_PKG_C8_RESIDENCY, Msr.Uint64);
+ @endcode
+**/
+#define MSR_XEON_D_PKG_C8_RESIDENCY 0x00000630
+
+/**
+ MSR information returned for MSR index #MSR_XEON_D_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_XEON_D_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_XEON_D_PKG_C9_RESIDENCY (0x00000631)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C9_RESIDENCY_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C9_RESIDENCY_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_PKG_C9_RESIDENCY_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PKG_C9_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_D_PKG_C9_RESIDENCY, Msr.Uint64);
+ @endcode
+**/
+#define MSR_XEON_D_PKG_C9_RESIDENCY 0x00000631
+
+/**
+ MSR information returned for MSR index #MSR_XEON_D_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_XEON_D_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_XEON_D_PKG_C10_RESIDENCY (0x00000632)
+ @param EAX Lower 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C10_RESIDENCY_REGISTER.
+ @param EDX Upper 32-bits of MSR value.
+ Described by the type MSR_XEON_D_PKG_C10_RESIDENCY_REGISTER.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_D_PKG_C10_RESIDENCY_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_D_PKG_C10_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_D_PKG_C10_RESIDENCY, Msr.Uint64);
+ @endcode
+**/
+#define MSR_XEON_D_PKG_C10_RESIDENCY 0x00000632
+
+/**
+ MSR information returned for MSR index #MSR_XEON_D_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_XEON_D_PKG_C10_RESIDENCY_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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h b/Core/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h
new file mode 100644
index 0000000000..b95f963b1e
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/XeonE7Msr.h
@@ -0,0 +1,254 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-7.
+
+**/
+
+#ifndef __XEON_E7_MSR_H__
+#define __XEON_E7_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_TURBO_RATIO_LIMIT);
+ AsmWriteMsr64 (MSR_XEON_E7_TURBO_RATIO_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_EVNT_SEL0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C8_PMON_CTR0);
+ AsmWriteMsr64 (MSR_XEON_E7_C8_PMON_CTR0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_CTRL);
+ AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_STATUS);
+ AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_STATUS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL);
+ AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_BOX_OVF_CTRL, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_EVNT_SEL0);
+ AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_EVNT_SEL0, Msr);
+ @endcode
+ @{
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_E7_C9_PMON_CTR0);
+ AsmWriteMsr64 (MSR_XEON_E7_C9_PMON_CTR0, Msr);
+ @endcode
+ @{
+**/
+#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/Core/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h b/Core/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h
new file mode 100644
index 0000000000..6695b69161
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/Msr/XeonPhiMsr.h
@@ -0,0 +1,1426 @@
+/** @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, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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,
+ December 2015, Chapter 35 Model-Specific-Registers (MSR), Section 35-15.
+
+**/
+
+#ifndef __XEON_PHI_MSR_H__
+#define __XEON_PHI_MSR_H__
+
+#include <Register/ArchitecturalMsr.h>
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_PHI_SMI_COUNT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_SMI_COUNT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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. 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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).
+ ///
+ 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] Precise 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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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;
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_OFFCORE_RSP_0);
+ AsmWriteMsr64 (MSR_XEON_PHI_OFFCORE_RSP_0, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_OFFCORE_RSP_1);
+ AsmWriteMsr64 (MSR_XEON_PHI_OFFCORE_RSP_1, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_LBR_SELECT);
+ AsmWriteMsr64 (MSR_XEON_PHI_LBR_SELECT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_LASTBRANCH_TOS);
+ AsmWriteMsr64 (MSR_XEON_PHI_LASTBRANCH_TOS, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_LER_FROM_LIP);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_LER_TO_LIP);
+ @endcode
+**/
+#define MSR_XEON_PHI_LER_TO_LIP 0x000001DE
+
+
+/**
+ Thread. See Table 35-2.
+
+ @param ECX MSR_XEON_PHI_IA32_PERF_GLOBAL_STAUS (0x0000038E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_IA32_PERF_GLOBAL_STAUS);
+ AsmWriteMsr64 (MSR_XEON_PHI_IA32_PERF_GLOBAL_STAUS, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_IA32_PERF_GLOBAL_STAUS 0x0000038E
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PEBS_ENABLE);
+ AsmWriteMsr64 (MSR_XEON_PHI_PEBS_ENABLE, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C3_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_C3_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C7_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_C7_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC0_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC0_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC6_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC6_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_CORE_C6_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_CORE_C6_RESIDENCY, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_CORE_C6_RESIDENCY 0x000003FF
+
+
+/**
+ Core. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_XEON_PHI_MC3_CTL (0x0000040C)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC3_CTL);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC3_CTL, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC3_CTL 0x0000040C
+
+
+/**
+ Core. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_XEON_PHI_MC3_STATUS (0x0000040D)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC3_STATUS);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC3_STATUS, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC3_STATUS 0x0000040D
+
+
+/**
+ Core. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs.".
+
+ @param ECX MSR_XEON_PHI_MC3_ADDR (0x0000040E)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC3_ADDR);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC3_ADDR, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC3_ADDR 0x0000040E
+
+
+/**
+ Core. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_XEON_PHI_MC4_CTL (0x00000410)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC4_CTL);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC4_CTL, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC4_CTL 0x00000410
+
+
+/**
+ Core. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_XEON_PHI_MC4_STATUS (0x00000411)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC4_STATUS);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC4_STATUS, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC4_STATUS 0x00000411
+
+
+/**
+ Core. 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_XEON_PHI_MC4_ADDR (0x00000412)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC4_ADDR);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC4_ADDR, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC4_ADDR 0x00000412
+
+
+/**
+ Package. See Section 15.3.2.1, "IA32_MCi_CTL MSRs.".
+
+ @param ECX MSR_XEON_PHI_MC5_CTL (0x00000414)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC5_CTL);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC5_CTL, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC5_CTL 0x00000414
+
+
+/**
+ Package. See Section 15.3.2.2, "IA32_MCi_STATUS MSRS.".
+
+ @param ECX MSR_XEON_PHI_MC5_STATUS (0x00000415)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC5_STATUS);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC5_STATUS, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC5_STATUS 0x00000415
+
+
+/**
+ Package. See Section 15.3.2.3, "IA32_MCi_ADDR MSRs.".
+
+ @param ECX MSR_XEON_PHI_MC5_ADDR (0x00000416)
+ @param EAX Lower 32-bits of MSR value.
+ @param EDX Upper 32-bits of MSR value.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_MC5_ADDR);
+ AsmWriteMsr64 (MSR_XEON_PHI_MC5_ADDR, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_MC5_ADDR 0x00000416
+
+
+/**
+ 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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_IA32_VMX_EPT_VPID_ENUM);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_IA32_VMX_FMFUNC);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ MSR_XEON_PHI_RAPL_POWER_UNIT_REGISTER Msr;
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_XEON_PHI_RAPL_POWER_UNIT);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_C2_RESIDENCY);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_C2_RESIDENCY, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PKG_POWER_INFO);
+ AsmWriteMsr64 (MSR_XEON_PHI_PKG_POWER_INFO, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_XEON_PHI_DRAM_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_ENERGY_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_PERF_STATUS);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_DRAM_POWER_INFO);
+ AsmWriteMsr64 (MSR_XEON_PHI_DRAM_POWER_INFO, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PP0_POWER_LIMIT);
+ AsmWriteMsr64 (MSR_XEON_PHI_PP0_POWER_LIMIT, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_PP0_ENERGY_STATUS);
+ @endcode
+**/
+#define MSR_XEON_PHI_PP0_ENERGY_STATUS 0x00000639
+
+
+/**
+ Package. Base TDP Ratio (R/O) See Table 35-20.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_NOMINAL);
+ @endcode
+**/
+#define MSR_XEON_PHI_CONFIG_TDP_NOMINAL 0x00000648
+
+
+/**
+ Package. ConfigTDP Level 1 ratio and power level (R/O). See Table 35-20.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_LEVEL1);
+ @endcode
+**/
+#define MSR_XEON_PHI_CONFIG_TDP_LEVEL1 0x00000649
+
+
+/**
+ Package. ConfigTDP Level 2 ratio and power level (R/O). See Table 35-20.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_LEVEL2);
+ @endcode
+**/
+#define MSR_XEON_PHI_CONFIG_TDP_LEVEL2 0x0000064A
+
+
+/**
+ Package. ConfigTDP Control (R/W) See Table 35-20.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_CONFIG_TDP_CONTROL);
+ AsmWriteMsr64 (MSR_XEON_PHI_CONFIG_TDP_CONTROL, Msr);
+ @endcode
+**/
+#define MSR_XEON_PHI_CONFIG_TDP_CONTROL 0x0000064B
+
+
+/**
+ Package. ConfigTDP Control (R/W) See Table 35-20.
+
+ @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.
+
+ <b>Example usage</b>
+ @code
+ UINT64 Msr;
+
+ Msr = AsmReadMsr64 (MSR_XEON_PHI_TURBO_ACTIVATION_RATIO);
+ AsmWriteMsr64 (MSR_XEON_PHI_TURBO_ACTIVATION_RATIO, Msr);
+ @endcode
+**/
+#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.
+
+ <b>Example usage</b>
+ @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
+**/
+#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/Core/UefiCpuPkg/Include/Register/SmramSaveStateMap.h b/Core/UefiCpuPkg/Include/Register/SmramSaveStateMap.h
new file mode 100644
index 0000000000..a7c7562df8
--- /dev/null
+++ b/Core/UefiCpuPkg/Include/Register/SmramSaveStateMap.h
@@ -0,0 +1,190 @@
+/** @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.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
new file mode 100644
index 0000000000..7cf7d8ca80
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
@@ -0,0 +1,46 @@
+## @file
+# This library defines some routines that are generic for IA32 family CPU.
+#
+# The library routines are UEFI specification compliant.
+#
+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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.asm
+ Ia32/InitializeFpu.S
+
+[Sources.X64]
+ X64/InitializeFpu.asm
+ X64/InitializeFpu.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ UefiCpuLib
+
diff --git a/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni
new file mode 100644
index 0000000000..1a1c0d2411
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.uni
@@ -0,0 +1,22 @@
+// /** @file
+// This library defines some routines that are generic for IA32 family CPU.
+//
+// The library routines are UEFI specification compliant.
+//
+// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S
new file mode 100644
index 0000000000..4972bc2e7f
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.S
@@ -0,0 +1,73 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* 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/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm
new file mode 100644
index 0000000000..3c31da98f6
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/Ia32/InitializeFpu.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------
+;*
+;* Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+;* This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;*
+;------------------------------------------------------------------------------
+
+
+ .686
+ .model flat,C
+ .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
+
+ .xmm
+ .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
+
+ push ebx
+
+ ;
+ ; Initialize floating point units
+ ;
+ finit
+ fldcw mFpuControlWord
+
+ ;
+ ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test
+ ; whether the processor supports SSE instruction.
+ ;
+ mov eax, 1
+ 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
+Done:
+ pop ebx
+
+ ret
+
+InitializeFloatingPointUnits ENDP
+
+END
diff --git a/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S
new file mode 100644
index 0000000000..97d9f72338
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* 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 0x037F (all exceptions
+# masked,double-extended-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 $0x037F
+ 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/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm
new file mode 100644
index 0000000000..331af15cc6
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseUefiCpuLib/X64/InitializeFpu.asm
@@ -0,0 +1,62 @@
+;------------------------------------------------------------------------------
+;*
+;* Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+;* This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* 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-extended-precision, round-to-nearest
+;
+mFpuControlWord DW 037Fh
+;
+; 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/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
new file mode 100644
index 0000000000..1fca66ef1b
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
@@ -0,0 +1,942 @@
+/** @file
+ Local APIC Library.
+
+ This local APIC library instance supports xAPIC mode only.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <Register/Cpuid.h>
+#include <Register/LocalApic.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Library internal functions
+//
+
+/**
+ 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 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_ADDRESS);
+
+ return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
+ (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 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 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_ADDRESS);
+
+ ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
+ ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
+
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, 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 ApicBaseMsr;
+
+ //
+ // Check to see if the CPU supports the APIC Base Address MSR
+ //
+ if (LocalApicBaseAddressMsrSupported ()) {
+ 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.
+
+ @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,
+ // 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, NULL, NULL, &ApicId);
+ 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);
+ 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);
+ 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;
+}
diff --git a/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
new file mode 100644
index 0000000000..7dd2714af3
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
@@ -0,0 +1,49 @@
+## @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 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni
new file mode 100644
index 0000000000..49b05e6cec
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.uni
@@ -0,0 +1,23 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
new file mode 100644
index 0000000000..38f5370cc3
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -0,0 +1,1037 @@
+/** @file
+ Local APIC Library.
+
+ This local APIC library instance supports x2APIC capable processors
+ which have xAPIC and x2APIC modes.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <Register/Cpuid.h>
+#include <Register/LocalApic.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Library internal functions
+//
+
+/**
+ 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 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_ADDRESS);
+
+ return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
+ (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 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 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_ADDRESS);
+
+ ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
+ ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
+
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, 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
+ )
+{
+ UINT32 MsrIndex;
+
+ ASSERT ((MmioOffset & 0xf) == 0);
+
+ if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) {
+ return MmioRead32 (GetLocalApicBaseAddress() + MmioOffset);
+ } else {
+ //
+ // DFR is not supported in x2APIC mode.
+ //
+ ASSERT (MmioOffset != XAPIC_ICR_DFR_OFFSET);
+ //
+ // Note that in x2APIC mode, ICR is a 64-bit MSR that needs special treatment. It
+ // is not supported in this function for simplicity.
+ //
+ ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
+
+ MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
+ return AsmReadMsr32 (MsrIndex);
+ }
+}
+
+/**
+ 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
+ )
+{
+ UINT32 MsrIndex;
+
+ ASSERT ((MmioOffset & 0xf) == 0);
+
+ if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) {
+ MmioWrite32 (GetLocalApicBaseAddress() + MmioOffset, Value);
+ } else {
+ //
+ // DFR is not supported in x2APIC mode.
+ //
+ ASSERT (MmioOffset != XAPIC_ICR_DFR_OFFSET);
+ //
+ // Note that in x2APIC mode, ICR is a 64-bit MSR that needs special treatment. It
+ // is not supported in this function for simplicity.
+ //
+ ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
+ ASSERT (MmioOffset != XAPIC_ICR_LOW_OFFSET);
+
+ MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
+ //
+ // The serializing semantics of WRMSR are relaxed when writing to the APIC registers.
+ // Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.
+ //
+ MemoryFence ();
+ AsmWriteMsr32 (MsrIndex, 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
+ )
+{
+ 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 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, ApicId << 24);
+ MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET, IcrLow);
+
+ //
+ // Wait for DeliveryStatus clear again
+ //
+ do {
+ 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
+ // interrupt in x2APIC mode.
+ //
+ MsrValue = LShiftU64 ((UINT64) ApicId, 32) | IcrLow;
+ AsmWriteMsr64 (X2APIC_MSR_ICR_ADDRESS, MsrValue);
+ }
+}
+
+//
+// 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
+ )
+{
+ MSR_IA32_APIC_BASE ApicBaseMsr;
+
+ 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_ADDRESS);
+ //
+ // Local APIC should have been enabled
+ //
+ ASSERT (ApicBaseMsr.Bits.En != 0);
+ if (ApicBaseMsr.Bits.Extd != 0) {
+ return LOCAL_APIC_MODE_X2APIC;
+ } else {
+ 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
+ )
+{
+ UINTN CurrentMode;
+ MSR_IA32_APIC_BASE 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) {
+ switch (ApicMode) {
+ 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);
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+ } else {
+ switch (ApicMode) {
+ case LOCAL_APIC_MODE_XAPIC:
+ //
+ // 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);
+ break;
+ case LOCAL_APIC_MODE_X2APIC:
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+ }
+}
+
+/**
+ 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;
+
+ 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,
+ // 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, NULL, NULL, &ApicId);
+ return ApicId;
+ }
+ AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
+ return RegEbx >> 24;
+ } else {
+ return GetApicId ();
+ }
+}
+
+/**
+ 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;
+ UINT32 InitApicId;
+
+ ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET);
+ if (GetApicMode () == LOCAL_APIC_MODE_XAPIC) {
+ ApicId = ((InitApicId = GetInitialApicId ()) < 0x100) ? (ApicId >> 24) : InitApicId;
+ }
+
+ 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);
+ 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);
+ 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;
+}
diff --git a/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
new file mode 100644
index 0000000000..53e186858f
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
@@ -0,0 +1,49 @@
+## @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 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni
new file mode 100644
index 0000000000..97f62273ba
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.uni
@@ -0,0 +1,23 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
new file mode 100644
index 0000000000..5d2816111f
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -0,0 +1,219 @@
+/** @file
+ CPU Exception Handler Library common functions.
+
+ Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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
+
+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"
+};
+
+#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.
+ @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;
+} \ No newline at end of file
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
new file mode 100644
index 0000000000..9c88012e0b
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -0,0 +1,284 @@
+/** @file
+ Common header file for CPU Exception Handler Library.
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <Ppi/VectorHandoffInfo.h>
+#include <Protocol/Cpu.h>
+#include <Library/BaseLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PrintLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SynchronizationLib.h>
+
+#define CPU_EXCEPTION_NUM 32
+#define CPU_INTERRUPT_NUM 256
+#define HOOKAFTER_STUB_SIZE 16
+
+#include "ArchInterruptDefs.h"
+
+#define CPU_EXCEPTION_HANDLER_LIB_HOB_GUID \
+ { \
+ 0xb21d9148, 0x9211, 0x4d8f, { 0xad, 0xd3, 0x66, 0xb1, 0x89, 0xc9, 0x2c, 0x83 } \
+ }
+
+//
+// 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 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.
+ @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.
+
+**/
+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 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
+ );
+
+#endif
+
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
new file mode 100644
index 0000000000..2d321494c2
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -0,0 +1,61 @@
+## @file
+# CPU Exception Handler library instance for DXE modules.
+#
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = DxeCpuExceptionHandlerLib
+ MODULE_UNI_FILE = DxeCpuExceptionHandlerLib.uni
+ FILE_GUID = B6E9835A-EDCF-4748-98A8-27D3C722E02D
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.1
+ LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32]
+ Ia32/ExceptionHandlerAsm.asm
+ Ia32/ExceptionHandlerAsm.S |GCC
+ Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
+
+[Sources.X64]
+ X64/ExceptionHandlerAsm.asm
+ X64/ExceptionHandlerAsm.S |GCC
+ X64/ArchExceptionHandler.c
+ X64/ArchInterruptDefs.h
+
+[Sources.common]
+ CpuExceptionCommon.h
+ CpuExceptionCommon.c
+ PeiDxeSmmCpuException.c
+ DxeException.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ SerialPortLib
+ PrintLib
+ SynchronizationLib
+ LocalApicLib
+ PeCoffGetEntryPointLib
+ MemoryAllocationLib
+ DebugLib
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni
new file mode 100644
index 0000000000..d59ad7fed0
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
new file mode 100644
index 0000000000..a61a52b19a
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -0,0 +1,204 @@
+/** @file
+ CPU exception handler library implemenation for DXE modules.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <PiDxe.h>
+#include "CpuExceptionCommon.h"
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+CONST UINTN mDoFarReturnFlag = 0;
+
+//
+// Image align size for DXE/SMM
+//
+CONST UINTN mImageAlignSize = SIZE_4KB;
+
+RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM];
+EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
+UINTN mEnabledInterruptNum = 0;
+
+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 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;
+
+ ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM);
+ ASSERT (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);
+ 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, (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);
+}
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
new file mode 100644
index 0000000000..7a183bf9a4
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -0,0 +1,204 @@
+/** @file
+ IA32 CPU Exception Handler functons.
+
+ Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 - %02x(%a) CPU Apic ID - %08x !!!!\n",
+ ExceptionType,
+ GetExceptionNameStr (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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
new file mode 100644
index 0000000000..a8d3556a80
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
@@ -0,0 +1,44 @@
+/** @file
+ Ia32 arch definition for CPU Exception Handler Library.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 _ARCH_CPU_INTERRUPT_DEFS_H_
+#define _ARCH_CPU_INTERRUPT_DEFS_H_
+
+typedef struct {
+ EFI_SYSTEM_CONTEXT_IA32 SystemContext;
+ BOOLEAN ExceptionDataFlag;
+ UINTN OldIdtHandler;
+} EXCEPTION_HANDLER_CONTEXT;
+
+//
+// Register Structure Definitions
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA Header;
+ EFI_SYSTEM_CONTEXT_IA32 SystemContext;
+} CPU_STATUS_CODE_TEMPLATE;
+
+typedef struct {
+ SPIN_LOCK SpinLock;
+ UINT32 ApicId;
+ UINT32 Attribute;
+ UINTN ExceptonHandler;
+ UINTN OldFlags;
+ UINTN OldCs;
+ UINTN OldIp;
+ UINTN ExceptionData;
+ UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
+} RESERVED_VECTORS_DATA;
+
+#endif
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
new file mode 100644
index 0000000000..3676809b4b
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
@@ -0,0 +1,667 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* 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;
+## insure FXSAVE/FXRSTOR is enabled in CR4...
+## ... while we're at it, make sure DE is also enabled...
+ mov $1, %eax
+ pushl %ebx # temporarily save value of ebx on stack
+ cpuid # use CPUID to determine if FXSAVE/FXRESTOR
+ # and DE are supported
+ popl %ebx # retore value of ebx that was overwritten
+ # by CPUID
+ movl %cr4, %eax
+ pushl %eax # push cr4 firstly
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support
+ jz L1
+ orl $BIT9, %eax # Set CR4.OSFXSR
+L1:
+ testl $BIT2, %edx # Test for Debugging Extensions support
+ jz L2
+ orl $BIT3, %eax # Set CR4.DE
+L2:
+ movl %eax, %cr4
+ 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
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support.
+ # edx still contains result from CPUID above
+ jz L3
+ .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
+L3:
+
+#; 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
+ movl $1, %eax
+ cpuid # use CPUID to determine if FXSAVE/FXRESTOR
+ # are supported
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support
+ jz L4
+ .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
+L4:
+ 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
+ lret # 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 (*NewVectorAddr, VectorNum, *OldVectorAddr);
+#-------------------------------------------------------------------------------------
+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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
new file mode 100644
index 0000000000..12bbec0690
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
@@ -0,0 +1,467 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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.Asm
+;
+; Abstract:
+;
+; IA32 CPU Exception Handler
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+
+;
+; CommonExceptionHandler()
+;
+CommonExceptionHandler PROTO C
+
+.data
+
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mDoFarReturnFlag:DWORD ; Do far return flag
+
+.code
+
+ALIGN 8
+
+;
+; exception handler stub table
+;
+AsmIdtVectorBegin:
+REPEAT 32
+ db 6ah ; push #VectorNum
+ db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
+ push eax
+ mov eax, CommonInterruptEntry
+ jmp eax
+ENDM
+AsmIdtVectorEnd:
+
+HookAfterStubBegin:
+ db 6ah ; push
+VectorNum:
+ 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]
+ xchg ecx, [esp] ; get vector number
+ bt mErrorCodeFlag, ecx
+ jnc @F
+ push [esp] ; addition push if exception data needed
+@@:
+ xchg ecx, [esp] ; restore ecx
+ push eax
+
+;----------------------------------------------------------------------------;
+; CommonInterruptEntry ;
+;----------------------------------------------------------------------------;
+; The follow algorithm is used for the common interrupt routine.
+; Entry from each interrupt with a push eax and eax=interrupt number
+; Stack:
+; +---------------------+
+; + EFlags +
+; +---------------------+
+; + CS +
+; +---------------------+
+; + EIP +
+; +---------------------+
+; + Error Code +
+; +---------------------+
+; + Vector Number +
+; +---------------------+
+; + EBP +
+; +---------------------+ <-- EBP
+CommonInterruptEntry PROC PUBLIC
+ cli
+ pop 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
+ ;
+ xchg ecx, [esp]
+ and ecx, 0FFh ; Vector number should be less than 256
+ 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
+
+ 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
+ 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, 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
+ push eax ; push cr4 firstly
+ test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
+ jz @F
+ or eax, BIT9 ; Set CR4.OSFXSR
+@@:
+ test edx, BIT2 ; Test for Debugging Extensions support
+ jz @F
+ or eax, BIT3 ; Set CR4.DE
+@@:
+ 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;
+ sub esp, 512
+ mov edi, esp
+ test edx, BIT24 ; Test for FXSAVE/FXRESTOR support.
+ ; edx still contains result from CPUID above
+ jz @F
+ 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]
+
+;; Prepare parameter and call
+ mov edx, esp
+ push edx
+ mov edx, dword ptr [ebp + 1 * 4]
+ push edx
+
+ ;
+ ; Call External Exception Handler
+ ;
+ mov eax, CommonExceptionHandler
+ call eax
+ add esp, 8
+
+ cli
+;; UINT32 ExceptionData;
+ add esp, 4
+
+;; FX_SAVE_STATE_IA32 FxSaveState;
+ mov esi, esp
+ mov eax, 1
+ cpuid ; use CPUID to determine if FXSAVE/FXRESTOR
+ ; are supported
+ test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
+ jz @F
+ 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
+
+ pop dword ptr [ebp - 8]
+ pop dword ptr [ebp - 4]
+ mov esp, ebp
+ pop ebp
+ add esp, 8
+ cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn
+ cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ jz ErrorCode
+ jmp dword ptr [esp - 16]
+ErrorCode:
+ sub esp, 4
+ jmp dword ptr [esp - 12]
+
+DoReturn:
+ cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET
+ jz DoIret
+ push [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
+ 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:
+;
+; Nothing
+;
+;
+; Input: [ebp][0] = Original ebp
+; [ebp][4] = Return address
+;
+; Output: Nothing
+;
+; Destroys: Nothing
+;-----------------------------------------------------------------------------;
+AsmGetTemplateAddressMap proc near public
+ 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
+
+ popad
+ pop ebp
+ ret
+AsmGetTemplateAddressMap ENDP
+
+;-------------------------------------------------------------------------------------
+; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);
+;-------------------------------------------------------------------------------------
+AsmVectorNumFixup proc near public
+ mov eax, dword ptr [esp + 8]
+ mov ecx, [esp + 4]
+ mov [ecx + (VectorNum - HookAfterStubBegin)], al
+ ret
+AsmVectorNumFixup ENDP
+END
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c
new file mode 100644
index 0000000000..c3fd8ae196
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c
@@ -0,0 +1,184 @@
+/** @file
+ CPU exception handler library implementation for PEIM module.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+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 <PiPei.h>
+#include "CpuExceptionCommon.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+//
+// Image Alignment size for PEI phase
+//
+CONST UINTN mImageAlignSize = 4;
+CONST UINTN mDoFarReturnFlag = 0;
+
+EFI_GUID mCpuExceptrionHandlerLibHobGuid = CPU_EXCEPTION_HANDLER_LIB_HOB_GUID;
+
+/**
+ Get exception handler data pointer from GUIDed HOb.
+
+ @return pointer to exception handler data.
+**/
+EXCEPTION_HANDLER_DATA *
+GetExceptionHandlerData (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
+
+ ExceptionHandlerData = NULL;
+ GuidHob = GetFirstGuidHob (&mCpuExceptrionHandlerLibHobGuid);
+ if (GuidHob != NULL) {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ ExceptionHandlerData = (EXCEPTION_HANDLER_DATA *)(*(UINTN *)DataInHob);
+ }
+ ASSERT (ExceptionHandlerData != NULL);
+ return ExceptionHandlerData;
+}
+
+/**
+ 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;
+ }
+
+ //
+ // Build location of CPU MP DATA buffer in HOB
+ //
+ BuildGuidDataHob (
+ &mCpuExceptrionHandlerLibHobGuid,
+ (VOID *)&ExceptionHandlerData,
+ sizeof(UINT64)
+ );
+
+ 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;
+} \ No newline at end of file
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
new file mode 100644
index 0000000000..d8a29977a4
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
@@ -0,0 +1,61 @@
+## @file
+# CPU Exception Handler library instance for PEI module.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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.asm
+ Ia32/ExceptionHandlerAsm.S |GCC
+ Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
+
+[Sources.X64]
+ X64/ExceptionHandlerAsm.asm
+ X64/ExceptionHandlerAsm.S |GCC
+ 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
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni
new file mode 100644
index 0000000000..8baf045a61
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
new file mode 100644
index 0000000000..02d56223c6
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
@@ -0,0 +1,294 @@
+/** @file
+ CPU Exception Library provides PEI/DXE/SMM CPU common exception handler.
+
+Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+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 <Library/DebugLib.h>
+
+/**
+ 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:
+ //
+ // Need to jmp to old IDT handler after this exception handler
+ //
+ ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
+ ExceptionHandlerContext->OldIdtHandler = ReservedVectors[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 (&ReservedVectors[ExceptionType].SpinLock)) {
+ //
+ // Need to execute old IDT handler before running this exception handler
+ //
+ ReservedVectors[ExceptionType].ApicId = GetApicId ();
+ ArchSaveExceptionContext (ExceptionType, SystemContext);
+ ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
+ ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler;
+ return;
+ }
+ //
+ // If failed to acquire SPIN_LOCK, check if it was locked by processor itself
+ //
+ if (ReservedVectors[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 (&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 ();
+ }
+ //
+ // Display ExceptionType, CPU information and Image information
+ //
+ DumpCpuContent (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 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);
+
+ 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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
new file mode 100644
index 0000000000..7e94e38ae1
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -0,0 +1,183 @@
+/** @file
+ CPU exception handler library implemenation for SEC/PEIM modules.
+
+Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
+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 <PiPei.h>
+#include "CpuExceptionCommon.h"
+
+//
+// Image Aglinment size for SEC/PEI phase
+//
+CONST UINTN mImageAlignSize = 4;
+CONST UINTN mDoFarReturnFlag = 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
+ )
+{
+ //
+ // Display ExceptionType, CPU information and Image information
+ //
+ DumpCpuContent (ExceptionType, SystemContext);
+
+ //
+ // Enter a dead loop.
+ //
+ CpuDeadLoop ();
+}
+
+/**
+ 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;
+ RESERVED_VECTORS_DATA ReservedVectorData[CPU_EXCEPTION_NUM];
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINTN IdtEntryCount;
+ UINT16 CodeSegment;
+ EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
+ UINTN Index;
+ UINTN InterruptHandler;
+
+ if (VectorInfo != NULL) {
+ SetMem ((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);
+ Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, 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 exeption library only setup CPU_EXCEPTION_NUM exception handler at most
+ //
+ IdtEntryCount = CPU_EXCEPTION_NUM;
+ }
+ //
+ // Use current CS as the segment selector of interrupt gate in IDT
+ //
+ CodeSegment = AsmReadCs ();
+
+ AsmGetTemplateAddressMap (&TemplateMap);
+ IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;
+ for (Index = 0; Index < IdtEntryCount; Index ++) {
+ IdtTable[Index].Bits.Selector = CodeSegment;
+ //
+ // Check reserved vectors attributes if has, only EFI_VECTOR_HANDOFF_DO_NOT_HOOK
+ // supported in this instance
+ //
+ if (VectorInfo != NULL) {
+ if (ReservedVectorData[Index].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {
+ continue;
+ }
+ }
+ //
+ // Update IDT entry
+ //
+ InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;
+ ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);
+ }
+ 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;
+} \ No newline at end of file
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
new file mode 100644
index 0000000000..951a6fe62c
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -0,0 +1,57 @@
+## @file
+# CPU Exception Handler library instance for SEC/PEI modules.
+#
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = SecPeiCpuExceptionHandlerLib
+ MODULE_UNI_FILE = SecPeiCpuExceptionHandlerLib.uni
+ FILE_GUID = CA4BBC99-DFC6-4234-B553-8B6586B7B113
+ 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.asm
+ Ia32/ExceptionHandlerAsm.S |GCC
+ Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
+
+[Sources.X64]
+ X64/ExceptionHandlerAsm.asm
+ X64/ExceptionHandlerAsm.S |GCC
+ 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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni
new file mode 100644
index 0000000000..b808c812f2
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
new file mode 100644
index 0000000000..549c74748d
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -0,0 +1,61 @@
+## @file
+# CPU Exception Handler library instance for SMM modules.
+#
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = SmmCpuExceptionHandlerLib
+ MODULE_UNI_FILE = SmmCpuExceptionHandlerLib.uni
+ FILE_GUID = 8D2C439B-3981-42ff-9CE5-1B50ECA502D6
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.1
+ LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32]
+ Ia32/ExceptionHandlerAsm.asm
+ Ia32/ExceptionHandlerAsm.S |GCC
+ Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
+
+[Sources.X64]
+ X64/ExceptionHandlerAsm.asm
+ X64/ExceptionHandlerAsm.S |GCC
+ X64/ArchExceptionHandler.c
+ X64/ArchInterruptDefs.h
+
+[Sources.common]
+ CpuExceptionCommon.h
+ CpuExceptionCommon.c
+ PeiDxeSmmCpuException.c
+ SmmException.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ SerialPortLib
+ PrintLib
+ SynchronizationLib
+ LocalApicLib
+ PeCoffGetEntryPointLib
+ DebugLib
+
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni
new file mode 100644
index 0000000000..a835101a2d
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.uni
@@ -0,0 +1,22 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
new file mode 100644
index 0000000000..7ad228c806
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
@@ -0,0 +1,133 @@
+/** @file
+ CPU exception handler library implemenation for SMM modules.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <PiSmm.h>
+#include "CpuExceptionCommon.h"
+
+CONST UINTN mDoFarReturnFlag = 1;
+
+//
+// Spin lock for CPU information display
+//
+SPIN_LOCK mDisplayMessageSpinLock;
+
+//
+// Image align size for DXE/SMM
+//
+CONST UINTN mImageAlignSize = SIZE_4KB;
+
+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 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
+ )
+{
+ 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 RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler, &mExceptionHandlerData);
+} \ No newline at end of file
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
new file mode 100644
index 0000000000..f711c3107b
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -0,0 +1,235 @@
+/** @file
+ x64 CPU Exception Handler.
+
+ Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 - %02x(%a) CPU Apic ID - %08x !!!!\n",
+ ExceptionType,
+ GetExceptionNameStr (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/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
new file mode 100644
index 0000000000..906480134a
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
@@ -0,0 +1,46 @@
+/** @file
+ X64 arch definition for CPU Exception Handler Library.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 _ARCH_CPU_INTERRUPT_DEFS_H_
+#define _ARCH_CPU_INTERRUPT_DEFS_H_
+
+typedef struct {
+ EFI_SYSTEM_CONTEXT_X64 SystemContext;
+ BOOLEAN ExceptionDataFlag;
+ UINTN OldIdtHandler;
+} EXCEPTION_HANDLER_CONTEXT;
+
+//
+// Register Structure Definitions
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA Header;
+ EFI_SYSTEM_CONTEXT_X64 SystemContext;
+} CPU_STATUS_CODE_TEMPLATE;
+
+typedef struct {
+ SPIN_LOCK SpinLock;
+ UINT32 ApicId;
+ UINT32 Attribute;
+ UINTN ExceptonHandler;
+ UINTN OldSs;
+ UINTN OldSp;
+ UINTN OldFlags;
+ UINTN OldCs;
+ UINTN OldIp;
+ UINTN ExceptionData;
+ UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
+} RESERVED_VECTORS_DATA;
+
+#endif
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
new file mode 100644
index 0000000000..6b62f095bd
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -0,0 +1,433 @@
+#------------------------------------------------------------------------------ ;
+# Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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)
+
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag
+.text
+
+#ifdef __APPLE__
+# macros are different between GNU and Xcode as.
+.macro IDT_MACRO
+ push $0
+#else
+.macro IDT_MACRO arg
+ push \arg
+#endif
+ jmp ASM_PFX(CommonInterruptEntry)
+.endm
+
+AsmIdtVectorBegin:
+ IDT_MACRO $0
+ IDT_MACRO $1
+ IDT_MACRO $2
+ IDT_MACRO $3
+ IDT_MACRO $4
+ IDT_MACRO $5
+ IDT_MACRO $6
+ IDT_MACRO $7
+ IDT_MACRO $8
+ IDT_MACRO $9
+ IDT_MACRO $10
+ IDT_MACRO $11
+ IDT_MACRO $12
+ IDT_MACRO $13
+ IDT_MACRO $14
+ IDT_MACRO $15
+ IDT_MACRO $16
+ IDT_MACRO $17
+ IDT_MACRO $18
+ IDT_MACRO $19
+ IDT_MACRO $20
+ IDT_MACRO $21
+ IDT_MACRO $22
+ IDT_MACRO $23
+ IDT_MACRO $24
+ IDT_MACRO $25
+ IDT_MACRO $26
+ IDT_MACRO $27
+ IDT_MACRO $28
+ IDT_MACRO $29
+ IDT_MACRO $30
+ IDT_MACRO $31
+AsmIdtVectorEnd:
+
+HookAfterStubHeaderBegin:
+ .byte 0x6a # push
+PatchVectorNum:
+ .byte 0 # 0 will be fixed
+ .byte 0xe9 # jmp ASM_PFX(HookAfterStubHeaderEnd)
+PatchFuncAddress:
+ .set HOOK_ADDRESS, ASM_PFX(HookAfterStubHeaderEnd) - . - 4
+ .long HOOK_ADDRESS # will be fixed
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
+ASM_PFX(HookAfterStubHeaderEnd):
+ pushq %rax
+ 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
+ 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
+ movq (%rax), %rax # restore rax
+
+#---------------------------------------;
+# 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.
+ andq $0x0FF, %rcx
+ cmp $32, %ecx # Intel reserved vector for exceptions?
+ jae NoErrorCode
+ pushq %rax
+ 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
+ mov %ds, %rax
+ pushq %rax
+ mov %es, %rax
+ pushq %rax
+ mov %fs, %rax
+ pushq %rax
+ mov %gs, %rax
+ 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
+ mov %rax, %es
+ popq %rax
+ mov %rax, %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
+ 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
+ lretq # far return
+DoIret:
+ iretq
+
+
+#-------------------------------------------------------------------------------------
+# AsmGetTemplateAddressMap (&AddressMap);
+#-------------------------------------------------------------------------------------
+# comments here for definition of address map
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
+ASM_PFX(AsmGetTemplateAddressMap):
+ pushq %rbp
+ movq %rsp, %rbp
+
+ leaq AsmIdtVectorBegin(%rip), %rax
+ movq %rax, (%rcx)
+ .set ENTRY_SIZE, ASM_PFX(HookAfterStubHeaderEnd) - HookAfterStubHeaderBegin
+ movq $(ENTRY_SIZE), 0x08(%rcx)
+ leaq HookAfterStubHeaderBegin(%rip), %rax
+ movq %rax, 0x10(%rcx)
+
+ popq %rbp
+ ret
+
+#-------------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# AsmVectorNumFixup (
+# IN VOID *NewVectorAddr, // RCX
+# IN UINT8 VectorNum // RDX
+# IN VOID *OldVectorAddr, // R8
+# );
+#-------------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
+ASM_PFX(AsmVectorNumFixup):
+ pushq %rbp
+ movq %rsp, %rbp
+
+# Patch vector #
+ movb %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx)
+
+# Patch Function address
+ subq %rcx, %r8 # Calculate the offset value
+ movl (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx), %eax
+ addq %r8, %rax
+ movl %eax, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx)
+
+ popq %rbp
+ ret
+
+#END
+
+
diff --git a/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
new file mode 100644
index 0000000000..cd21ec4c90
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
@@ -0,0 +1,389 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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.Asm
+;
+; Abstract:
+;
+; x64 CPU Exception Handler
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+;
+; CommonExceptionHandler()
+;
+externdef CommonExceptionHandler:near
+
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mDoFarReturnFlag:QWORD ; Do far return flag
+
+data SEGMENT
+
+.code
+
+ALIGN 8
+
+AsmIdtVectorBegin:
+REPEAT 32
+ db 6ah ; push #VectorNum
+ db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
+ push rax
+ mov rax, CommonInterruptEntry
+ jmp rax
+ENDM
+AsmIdtVectorEnd:
+
+HookAfterStubHeaderBegin:
+ db 6ah ; push
+@VectorNum:
+ 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
+ push rcx
+ mov rcx, [rax + 8]
+ bt mErrorCodeFlag, ecx
+ jnc @F
+ push [rsp] ; push additional rcx to make stack alignment
+@@:
+ xchg rcx, [rsp] ; restore rcx, save Exception Number in stack
+ push [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.
+CommonInterruptEntry PROC PUBLIC
+ 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, 0FFh
+ 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
+ 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 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]
+
+;; 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
+ mov rax, CommonExceptionHandler
+ call rax
+ add rsp, 4 * 8 + 8
+
+ 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
+ cmp qword ptr [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn
+ cmp qword ptr [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ jz ErrorCode
+ jmp qword ptr [rsp - 32]
+ErrorCode:
+ sub rsp, 8
+ jmp qword ptr [rsp - 24]
+
+DoReturn:
+ cmp 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 rax, [rax] ; restore rax
+ popfq ; restore EFLAGS
+ DB 48h ; 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
+ ret
+AsmGetTemplateAddressMap ENDP
+
+;-------------------------------------------------------------------------------------
+; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);
+;-------------------------------------------------------------------------------------
+AsmVectorNumFixup PROC
+ mov rax, rdx
+ mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al
+ ret
+AsmVectorNumFixup ENDP
+
+END
diff --git a/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
new file mode 100644
index 0000000000..6a6bf765c2
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -0,0 +1,2147 @@
+/** @file
+ MTRR setting library
+
+ Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <Base.h>
+
+#include <Library/MtrrLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+#define OR_SEED 0x0101010101010101ull
+#define CLEAR_SEED 0xFFFFFFFFFFFFFFFFull
+
+//
+// Context to save and restore when MTRRs are programmed
+//
+typedef struct {
+ UINTN Cr4;
+ BOOLEAN InterruptState;
+} MTRR_CONTEXT;
+
+//
+// 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
+};
+
+/**
+ Worker function returns the variable MTRR count for the CPU.
+
+ @return Variable MTRR count
+
+**/
+UINT32
+GetVariableMtrrCountWorker (
+ VOID
+ )
+{
+ UINT32 VariableMtrrCount;
+
+ 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 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
+ )
+{
+ if (MtrrSetting == NULL) {
+ return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);
+ } else {
+ return (MTRR_MEMORY_CACHE_TYPE) (MtrrSetting->MtrrDefType & 0x7);
+ }
+}
+
+
+/**
+ 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
+PreMtrrChange (
+ OUT MTRR_CONTEXT *MtrrContext
+ )
+{
+ //
+ // 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
+ //
+ AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0);
+}
+
+/**
+ 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
+PostMtrrChangeEnableCache (
+ 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
+PostMtrrChange (
+ IN MTRR_CONTEXT *MtrrContext
+ )
+{
+ //
+ // Enable Cache MTRR
+ //
+ AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);
+
+ PostMtrrChangeEnableCache (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 <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if (MtrrSetting == NULL) {
+ 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);
+ } 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] MemoryCacheType 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] LastMsrNum 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] ReturnClearMask The bits to clear in the fixed MTRR MSR.
+ @param[out] ReturnOrMask 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
+ProgramFixedMtrr (
+ IN UINT64 MemoryCacheType,
+ IN OUT UINT64 *Base,
+ IN OUT UINT64 *Length,
+ IN OUT UINT32 *LastMsrNum,
+ OUT UINT64 *ReturnClearMask,
+ OUT UINT64 *ReturnOrMask
+ )
+{
+ UINT32 MsrNum;
+ UINT32 LeftByteShift;
+ UINT32 RightByteShift;
+ UINT64 OrMask;
+ UINT64 ClearMask;
+ UINT64 SubLength;
+
+ //
+ // Find the fixed MTRR index to be programmed
+ //
+ for (MsrNum = *LastMsrNum + 1; 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;
+ }
+
+ //
+ // Find the begin offset in fixed MTRR and calculate byte offset of left shift
+ //
+ LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)
+ / mMtrrLibFixedMtrrTable[MsrNum].Length;
+
+ if (LeftByteShift >= 8) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Find the end offset in fixed MTRR and calculate byte offset of right shift
+ //
+ SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - LeftByteShift);
+ if (*Length >= SubLength) {
+ RightByteShift = 0;
+ } else {
+ RightByteShift = 8 - LeftByteShift -
+ (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrNum].Length;
+ if ((LeftByteShift >= 8) ||
+ (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrNum].Length) != 0)
+ ) {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Update SubLength by actual length
+ //
+ SubLength = *Length;
+ }
+
+ ClearMask = CLEAR_SEED;
+ OrMask = MultU64x32 (OR_SEED, (UINT32)MemoryCacheType);
+
+ 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;
+
+ *LastMsrNum = MsrNum;
+ *ReturnClearMask = ClearMask;
+ *ReturnOrMask = OrMask;
+
+ 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] FirmwareVariableMtrrCount The number of variable MTRRs available to firmware
+ @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
+MtrrGetMemoryAttributeInVariableMtrrWorker (
+ IN MTRR_VARIABLE_SETTINGS *VariableSettings,
+ IN UINTN FirmwareVariableMtrrCount,
+ IN UINT64 MtrrValidBitsMask,
+ IN UINT64 MtrrValidAddressMask,
+ OUT VARIABLE_MTRR *VariableMtrr
+ )
+{
+ UINTN Index;
+ UINT32 UsedMtrr;
+
+ ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);
+ for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {
+ if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 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;
+}
+
+
+/**
+ 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 paramter 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
+ );
+}
+
+
+/**
+ Checks overlap between given memory range and MTRRs.
+
+ @param[in] FirmwareVariableMtrrCount The number of variable MTRRs available
+ to firmware.
+ @param[in] Start The start address of memory range.
+ @param[in] End The end address of memory range.
+ @param[in] VariableMtrr The array to shadow variable MTRRs content
+
+ @retval TRUE Overlap exists.
+ @retval FALSE No overlap.
+
+**/
+BOOLEAN
+CheckMemoryAttributeOverlap (
+ IN UINTN FirmwareVariableMtrrCount,
+ IN PHYSICAL_ADDRESS Start,
+ IN PHYSICAL_ADDRESS End,
+ IN VARIABLE_MTRR *VariableMtrr
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < FirmwareVariableMtrrCount; 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[in] Index The index of the array VariableMtrr to be invalidated
+ @param[in] VariableMtrr The array to shadow variable MTRRs content
+ @param[out] 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;
+}
+
+
+/**
+ Combines memory attributes.
+
+ If overlap exists between given memory range and MTRRs, try to combine them.
+
+ @param[in] FirmwareVariableMtrrCount The number of variable MTRRs
+ available to firmware.
+ @param[in] Attributes 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] VariableMtrr The array to shadow variable MTRRs content
+ @param[in, out] UsedMtrr The number of MTRRs which has already been used
+ @param[out] 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 UINT32 FirmwareVariableMtrrCount,
+ 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;
+ BOOLEAN CoveredByExistingMtrr;
+
+ *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;
+}
+
+
+/**
+ Calculates the maximum value which is a power of 2, but less the MemoryLength.
+
+ @param[in] 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;
+}
+
+
+/**
+ Determines 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[in] BaseAddress Length of Memory to program MTRR
+ @param[in] Length Length of Memory to program MTRR
+ @param[in] MtrrNumber Pointer to the number of necessary MTRRs
+
+ @retval TRUE Positive direction is better.
+ FALSE Negative 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[in, out] VariableSettings Variable MTRR settings
+ @param[in] VariableMtrrCount Number of variable MTRRs
+ @param[in, out] VariableMtrr Shadow of variable MTRR contents
+
+**/
+VOID
+InvalidateMtrr (
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
+ IN UINTN VariableMtrrCount,
+ IN OUT VARIABLE_MTRR *VariableMtrr
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {
+ VariableSettings->Mtrr[Index].Base = 0;
+ VariableSettings->Mtrr[Index].Mask = 0;
+ VariableMtrr[Index].Used = FALSE;
+ }
+ }
+}
+
+
+/**
+ Programs variable MTRRs
+
+ This function programs variable MTRRs
+
+ @param[in, out] VariableSettings Variable MTRR settings.
+ @param[in] MtrrNumber Index of MTRR to program.
+ @param[in] BaseAddress Base address of memory region.
+ @param[in] Length Length of memory region.
+ @param[in] MemoryCacheType Memory type to set.
+ @param[in] MtrrValidAddressMask The valid address mask for MTRR
+
+**/
+VOID
+ProgramVariableMtrr (
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
+ IN UINTN MtrrNumber,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 MemoryCacheType,
+ IN UINT64 MtrrValidAddressMask
+ )
+{
+ UINT64 TempQword;
+
+ //
+ // MTRR Physical Base
+ //
+ TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;
+ VariableSettings->Mtrr[MtrrNumber].Base = TempQword;
+
+ //
+ // MTRR Physical Mask
+ //
+ TempQword = ~(Length - 1);
+ VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;
+}
+
+
+/**
+ Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.
+
+ If MtrrSetting is not NULL, gets the default memory attribute from input
+ MTRR settings buffer.
+ If MtrrSetting is NULL, gets the default memory attribute from MSR.
+
+ @param[in] MtrrSetting A buffer holding all MTRRs content.
+ @param[in] MtrrType MTRR memory type
+
+ @return The enum item in MTRR_MEMORY_CACHE_TYPE
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+GetMemoryCacheTypeFromMtrrType (
+ IN MTRR_SETTINGS *MtrrSetting,
+ 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 MtrrGetDefaultMemoryTypeWorker (MtrrSetting);
+ }
+}
+
+/**
+ 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 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_MSR_VALID_MASK;
+ *MtrrValidAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
+ }
+}
+
+
+/**
+ 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 10.11.4.1.
+
+ @param[in] MtrrType1 The first kind of Memory type
+ @param[in] MtrrType2 The second kind of memory type
+
+**/
+UINT64
+MtrrPrecedence (
+ IN UINT64 MtrrType1,
+ IN 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;
+}
+
+/**
+ 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
+ )
+{
+ 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;
+ MTRR_VARIABLE_SETTINGS VariableSettings;
+
+ //
+ // Check if MTRR is enabled, if not, return UC as attribute
+ //
+ if (MtrrSetting == NULL) {
+ TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
+ } else {
+ TempQword = MtrrSetting->MtrrDefType;
+ }
+ 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;
+ if (MtrrSetting == NULL) {
+ TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
+ } else {
+ TempQword = MtrrSetting->Fixed.Mtrr[Index];
+ }
+ MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
+ return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
+ }
+ }
+ }
+ }
+ MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
+
+ MtrrGetVariableMtrrWorker (
+ MtrrSetting,
+ GetVariableMtrrCountWorker (),
+ &VariableSettings
+ );
+
+ MtrrGetMemoryAttributeInVariableMtrrWorker (
+ &VariableSettings,
+ GetFirmwareVariableMtrrCountWorker (),
+ MtrrValidBitsMask,
+ MtrrValidAddressMask,
+ VariableMtrr
+ );
+
+ //
+ // Go through the variable MTRR
+ //
+ VariableMtrrCount = GetVariableMtrrCountWorker ();
+ 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 (MtrrSetting, MtrrType);
+
+ return CacheType;
+}
+
+
+/**
+ 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);
+}
+
+/**
+ Worker function prints all MTRRs for debugging.
+
+ If MtrrSetting is not NULL, print MTRR settings from 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 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"));
+
+ if (MtrrSetting != NULL) {
+ Mtrrs = MtrrSetting;
+ } else {
+ MtrrGetAllMtrrs (&LocalMtrrs);
+ Mtrrs = &LocalMtrrs;
+ }
+
+ DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));
+ }
+
+ VariableMtrrCount = GetVariableMtrrCount ();
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
+ Index,
+ Mtrrs->Variables.Mtrr[Index].Base,
+ Mtrrs->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 (Mtrrs->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 ();
+
+ Limit = BIT36 - 1;
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ Limit = LShiftU64 (1, RegEax & 0xff) - 1;
+ }
+ Base = BASE_1MB;
+ PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
+ do {
+ MemoryType = MtrrGetMemoryAttributeByAddressWorker (Mtrrs, 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;
+ RangeLimit = Limit;
+ NoRangeLimit = Limit;
+
+ for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {
+ if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
+ //
+ // If mask is not valid, then do not display range
+ //
+ continue;
+ }
+ MtrrBase = (Mtrrs->Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));
+ MtrrLimit = MtrrBase + ((~(Mtrrs->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 (Base < Limit);
+ DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));
+ );
+}
+
+
+/**
+ This function prints all MTRRs for debugging.
+**/
+VOID
+EFIAPI
+MtrrDebugPrintAllMtrrs (
+ VOID
+ )
+{
+ MtrrDebugPrintAllMtrrsWorker (NULL);
+}
+
+
+/**
+ Worker function attempts to set the attributes for a memory range.
+
+ If MtrrSettings is not NULL, set the attributes into the input MTRR
+ settings buffer.
+ If MtrrSettings is NULL, set the attributes into MTRRs registers.
+
+ @param[in, out] MtrrSetting A buffer holding all MTRRs content.
+ @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.
+
+**/
+RETURN_STATUS
+MtrrSetMemoryAttributeWorker (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ 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;
+ BOOLEAN OverwriteExistingMtrr;
+ UINT32 FirmwareVariableMtrrCount;
+ MTRR_CONTEXT MtrrContext;
+ BOOLEAN MtrrContextValid;
+ BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
+ BOOLEAN FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTRR];
+ MTRR_FIXED_SETTINGS WorkingFixedSettings;
+ UINT32 VariableMtrrCount;
+ MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
+ BOOLEAN ProgramVariableSettings;
+ MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
+ UINT32 Index;
+ UINT64 ClearMask;
+ UINT64 OrMask;
+ UINT64 NewValue;
+ MTRR_VARIABLE_SETTINGS *VariableSettings;
+
+ MtrrContextValid = FALSE;
+ VariableMtrrCount = 0;
+ ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings));
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ FixedSettingsValid[Index] = FALSE;
+ FixedSettingsModified[Index] = FALSE;
+ }
+ ProgramVariableSettings = FALSE;
+
+ if (!IsMtrrSupported ()) {
+ Status = RETURN_UNSUPPORTED;
+ goto Done;
+ }
+
+ 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;
+ if (BaseAddress < BASE_1MB) {
+ MsrNum = (UINT32)-1;
+ while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
+ Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);
+ if (RETURN_ERROR (Status)) {
+ goto Done;
+ }
+ if (MtrrSetting != NULL) {
+ MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;
+ } else {
+ if (!FixedSettingsValid[MsrNum]) {
+ WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);
+ FixedSettingsValid[MsrNum] = TRUE;
+ }
+ NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+ if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {
+ WorkingFixedSettings.Mtrr[MsrNum] = NewValue;
+ FixedSettingsModified[MsrNum] = TRUE;
+ }
+ }
+ }
+
+ 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;
+ }
+
+ //
+ // Read all variable MTRRs
+ //
+ VariableMtrrCount = GetVariableMtrrCountWorker ();
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
+ if (MtrrSetting != NULL) {
+ VariableSettings = &MtrrSetting->Variables;
+ } else {
+ MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);
+ CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
+ ProgramVariableSettings = TRUE;
+ VariableSettings = &WorkingVariableSettings;
+ }
+
+ //
+ // Check for overlap
+ //
+ UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (
+ VariableSettings,
+ FirmwareVariableMtrrCount,
+ MtrrValidBitsMask,
+ MtrrValidAddressMask,
+ VariableMtrr
+ );
+ OverLap = CheckMemoryAttributeOverlap (
+ FirmwareVariableMtrrCount,
+ BaseAddress,
+ BaseAddress + Length - 1,
+ VariableMtrr
+ );
+ if (OverLap) {
+ Status = CombineMemoryAttribute (
+ FirmwareVariableMtrrCount,
+ MemoryType,
+ &BaseAddress,
+ &Length,
+ VariableMtrr,
+ &UsedMtrr,
+ &OverwriteExistingMtrr
+ );
+ if (RETURN_ERROR (Status)) {
+ goto Done;
+ }
+
+ if (Length == 0) {
+ //
+ // Combined successfully, invalidate the now-unused MTRRs
+ //
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, 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 == MtrrGetDefaultMemoryTypeWorker (MtrrSetting))) {
+ //
+ // Invalidate the now-unused MTRRs
+ //
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, 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 (VariableSettings, VariableMtrrCount, VariableMtrr);
+
+ //
+ // Find first unused MTRR
+ //
+ for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & 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 < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ break;
+ }
+ }
+
+ ProgramVariableMtrr (
+ VariableSettings,
+ 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 < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ break;
+ }
+ }
+
+ ProgramVariableMtrr (
+ VariableSettings,
+ MsrNum,
+ BaseAddress,
+ Length,
+ MemoryType,
+ MtrrValidAddressMask
+ );
+ BaseAddress += Length;
+ TempQword = Length - TempQword;
+ MemoryType = MTRR_CACHE_UNCACHEABLE;
+ }
+
+ do {
+ //
+ // Find unused MTRR
+ //
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ break;
+ }
+ }
+
+ Length = Power2MaxMemory (TempQword);
+ if (!Positive) {
+ BaseAddress -= Length;
+ }
+
+ ProgramVariableMtrr (
+ VariableSettings,
+ MsrNum,
+ BaseAddress,
+ Length,
+ MemoryType,
+ MtrrValidAddressMask
+ );
+
+ if (Positive) {
+ BaseAddress += Length;
+ }
+ TempQword -= Length;
+
+ } while (TempQword > 0);
+
+Done:
+
+ //
+ // Write fixed MTRRs that have been modified
+ //
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ if (FixedSettingsModified[Index]) {
+ if (!MtrrContextValid) {
+ PreMtrrChange (&MtrrContext);
+ MtrrContextValid = TRUE;
+ }
+ AsmWriteMsr64 (
+ mMtrrLibFixedMtrrTable[Index].Msr,
+ WorkingFixedSettings.Mtrr[Index]
+ );
+ }
+ }
+
+ //
+ // Write variable MTRRs
+ //
+ if (ProgramVariableSettings) {
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if (WorkingVariableSettings.Mtrr[Index].Base != OriginalVariableSettings.Mtrr[Index].Base ||
+ WorkingVariableSettings.Mtrr[Index].Mask != OriginalVariableSettings.Mtrr[Index].Mask ) {
+ if (!MtrrContextValid) {
+ PreMtrrChange (&MtrrContext);
+ MtrrContextValid = TRUE;
+ }
+ AsmWriteMsr64 (
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1),
+ WorkingVariableSettings.Mtrr[Index].Base
+ );
+ AsmWriteMsr64 (
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1,
+ WorkingVariableSettings.Mtrr[Index].Mask
+ );
+ }
+ }
+ }
+ if (MtrrContextValid) {
+ PostMtrrChange (&MtrrContext);
+ }
+
+ DEBUG((DEBUG_CACHE, " Status = %r\n", Status));
+ if (!RETURN_ERROR (Status)) {
+ if (MtrrSetting != NULL) {
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_MTRR_ENABLED;
+ }
+ MtrrDebugPrintAllMtrrsWorker (MtrrSetting);
+ }
+
+ return Status;
+}
+
+/**
+ 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] 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
+ )
+{
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+ return MtrrSetMemoryAttributeWorker (
+ NULL,
+ BaseAddress,
+ Length,
+ Attribute
+ );
+}
+
+/**
+ 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.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttributeInMtrrSettings (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
+ )
+{
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%016lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+ return MtrrSetMemoryAttributeWorker (
+ MtrrSetting,
+ 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 <= 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[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;
+ }
+
+ PreMtrrChange (&MtrrContext);
+ MtrrSetVariableMtrrWorker (VariableSettings);
+ PostMtrrChange (&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;
+ }
+
+ PreMtrrChange (&MtrrContext);
+ MtrrSetFixedMtrrWorker (FixedSettings);
+ PostMtrrChange (&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 (MTRR_LIB_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;
+ }
+
+ PreMtrrChange (&MtrrContext);
+
+ //
+ // 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);
+
+ PostMtrrChangeEnableCache (&MtrrContext);
+
+ MtrrDebugPrintAllMtrrs ();
+
+ return MtrrSetting;
+}
+
+
+/**
+ 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/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
new file mode 100644
index 0000000000..01a4d84da0
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
@@ -0,0 +1,46 @@
+## @file
+# MTRR library provides APIs for MTRR operation.
+#
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni
new file mode 100644
index 0000000000..34753a089a
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/MtrrLib/MtrrLib.uni
@@ -0,0 +1,22 @@
+// /** @file
+// MTRR library provides APIs for MTRR operation.
+//
+// MTRR library provides APIs for MTRR operation.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c
new file mode 100644
index 0000000000..ad3e9090c6
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.c
@@ -0,0 +1,90 @@
+/** @file
+Null instance of Platform Sec Lib.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.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
+ )
+{
+ 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/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
new file mode 100644
index 0000000000..3f8868adee
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
@@ -0,0 +1,37 @@
+## @file
+# Library functions for PlatformSecLib.
+#
+# Null instance of Platform Sec Lib.
+#
+# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni
new file mode 100644
index 0000000000..d7212f0351
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.uni
@@ -0,0 +1,20 @@
+// /** @file
+// Library functions for PlatformSecLib.
+//
+// Null instance of Platform Sec Library.
+//
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c
new file mode 100644
index 0000000000..714b99eec4
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/IpfTimerLib.c
@@ -0,0 +1,216 @@
+/** @file
+ Timer Library functions built upon ITC on IPF.
+
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ 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 <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PalLib.h>
+
+
+/**
+ 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/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
new file mode 100644
index 0000000000..a25e94a61a
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
@@ -0,0 +1,67 @@
+## @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 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# 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
+ 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 IPF
+#
+
+[Sources.Ia32, Sources.X64]
+ X86TimerLib.c
+
+[Sources.IPF]
+ IpfTimerLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[LibraryClasses.IA32, LibraryClasses.X64]
+ PcdLib
+ DebugLib
+ LocalApicLib
+
+[LibraryClasses.IPF]
+ PalLib
+
+
+[Pcd.IA32, Pcd.X64]
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES
+
diff --git a/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni
new file mode 100644
index 0000000000..da9e4d8191
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.uni
@@ -0,0 +1,31 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php.
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
new file mode 100644
index 0000000000..f703d7e477
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
@@ -0,0 +1,266 @@
+/** @file
+ 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 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ 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 <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
+
+/**
+ Internal function to return the frequency of the local APIC timer.
+
+ @return The frequency of the timer in Hz.
+
+**/
+UINT32
+EFIAPI
+InternalX86GetTimerFrequency (
+ VOID
+ )
+{
+ UINTN Divisor;
+
+ GetApicTimerState (&Divisor, NULL, NULL);
+ return PcdGet32(PcdFSBClock) / (UINT32)Divisor;
+}
+
+/**
+ 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().
+
+ 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.
+
+**/
+VOID
+EFIAPI
+InternalX86Delay (
+ IN UINT32 Delay
+ )
+{
+ INT32 Ticks;
+ UINT32 Times;
+ UINT32 InitCount;
+ UINT32 StartTick;
+
+ //
+ // 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.
+ //
+ InitCount = GetApicTimerInitCount ();
+ ASSERT (InitCount != 0);
+ Times = Delay / (InitCount / 2);
+ Delay = Delay % (InitCount / 2);
+
+ //
+ // Get Start Tick and do delay
+ //
+ 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);
+}
+
+/**
+ 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
+ )
+{
+ InternalX86Delay (
+ (UINT32)DivU64x32 (
+ MultU64x64 (
+ InternalX86GetTimerFrequency (),
+ MicroSeconds
+ ),
+ 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 The value of NanoSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ InternalX86Delay (
+ (UINT32)DivU64x32 (
+ MultU64x64 (
+ InternalX86GetTimerFrequency (),
+ NanoSeconds
+ ),
+ 1000000000u
+ )
+ );
+ 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 (UINT64)GetApicTimerCurrentCount ();
+}
+
+/**
+ 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 = (UINT64)GetApicTimerInitCount ();
+ }
+
+ if (EndValue != NULL) {
+ *EndValue = 0;
+ }
+
+ return (UINT64) InternalX86GetTimerFrequency ();
+}
+
+/**
+ 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/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
new file mode 100644
index 0000000000..3e480e1761
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
@@ -0,0 +1,658 @@
+/** @file
+The CPU specific programming for PiSmmCpuDxeSmm module.
+
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiSmm.h>
+#include <Library/SmmCpuFeaturesLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Register/Cpuid.h>
+#include <Register/SmramSaveStateMap.h>
+
+//
+// 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
+
+//
+// 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) {
+ 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) {
+ //
+ // 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;
+ }
+ }
+ }
+}
+
+/**
+ 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
+ )
+{
+}
+
+/**
+ 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
+ )
+{
+}
+
+/**
+ 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_PARAMTER 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_PARAMTER 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/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
new file mode 100644
index 0000000000..1735062b17
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
@@ -0,0 +1,39 @@
+## @file
+# The CPU specific programming for PiSmmCpuDxeSmm module.
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ MemoryAllocationLib
+ DebugLib
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES
diff --git a/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
new file mode 100644
index 0000000000..322aa8bb5a
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
@@ -0,0 +1,18 @@
+// /** @file
+// The CPU specific programming for PiSmmCpuDxeSmm module.
+//
+// Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c
new file mode 100644
index 0000000000..efb61fa6f8
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.c
@@ -0,0 +1,108 @@
+/** @file
+SMM CPU Platform Hook NULL library instance.
+
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiSmm.h>
+#include <Library/SmmCpuPlatformHookLib.h>
+
+/**
+ 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/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
new file mode 100644
index 0000000000..4dea5fb4e1
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
@@ -0,0 +1,40 @@
+## @file
+# SMM CPU Platform Hook NULL library instance.
+#
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 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/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni
new file mode 100644
index 0000000000..46de9f3494
--- /dev/null
+++ b/Core/UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.uni
@@ -0,0 +1,18 @@
+// /** @file
+// SMM CPU Platform Hook NULL library instance.
+//
+// Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/License.txt b/Core/UefiCpuPkg/License.txt
new file mode 100644
index 0000000000..be68999be6
--- /dev/null
+++ b/Core/UefiCpuPkg/License.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2012, Intel Corporation. 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.
+
+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 HOLDER 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.
diff --git a/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c
new file mode 100644
index 0000000000..aaeaa06729
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.c
@@ -0,0 +1,425 @@
+/** @file
+PiSmmCommunication PEI Driver.
+
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiPei.h>
+#include <PiDxe.h>
+#include <PiSmm.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SmmCommunication.h>
+#include <Ppi/SmmCommunication.h>
+#include <Ppi/SmmAccess.h>
+#include <Ppi/SmmControl.h>
+#include <Guid/AcpiS3Context.h>
+
+#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_SUCEESS
+ @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/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
new file mode 100644
index 0000000000..5cb596c564
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
@@ -0,0 +1,70 @@
+## @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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni
new file mode 100644
index 0000000000..697bb2b3d9
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.uni
@@ -0,0 +1,21 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni
new file mode 100644
index 0000000000..62e3f97928
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPeiExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// PiSmmCommunicationPei Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"SMM Communication PEI Module"
diff --git a/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h
new file mode 100644
index 0000000000..3dd5ac6e38
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPrivate.h
@@ -0,0 +1,30 @@
+/** @file
+PiSmmCommunication private data structure
+
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _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/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c
new file mode 100644
index 0000000000..077eacce88
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c
@@ -0,0 +1,269 @@
+/** @file
+PiSmmCommunication SMM Driver.
+
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiSmm.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmmMemLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmCommunication.h>
+#include <Protocol/AcpiTable.h>
+#include <Ppi/SmmCommunication.h>
+#include <Guid/Acpi.h>
+
+#include "PiSmmCommunicationPrivate.h"
+
+EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {
+ SMM_COMMUNICATION_SIGNATURE
+};
+
+EFI_SMM_COMMUNICATION_ACPI_TABLE mSmmCommunicationAcpiTable = {
+ {
+ {
+ EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE,
+ sizeof (EFI_SMM_COMMUNICATION_ACPI_TABLE),
+ 0x1, // Revision
+ 0x0, // Checksum
+ {0x0}, // OemId[6]
+ 0x0, // OemTableId
+ 0x0, // OemRevision
+ 0x0, // CreatorId
+ 0x0 // CreatorRevision
+ },
+ {0x0}, // Identifier
+ OFFSET_OF (EFI_SMM_COMMUNICATION_ACPI_TABLE, SwSmiNumber) // DataOffset
+ },
+ 0x0, // SwSmiNumber
+ 0x0 // BufferPtrAddress
+};
+
+/**
+ 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_SUCEESS
+ @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_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ UINTN TableKey;
+ UINT64 OemTableId;
+ EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
+
+ CopyMem (
+ mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.OemId,
+ PcdGetPtr (PcdAcpiDefaultOemId),
+ sizeof (mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.OemId)
+ );
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (&mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.OemTableId, &OemTableId, sizeof (UINT64));
+ mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
+ mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+ mSmmCommunicationAcpiTable.UefiAcpiDataTable.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+ //
+ // 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));
+
+ //
+ // Set ACPI table
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ mSmmCommunicationAcpiTable.SwSmiNumber = (UINT32)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));
+ mSmmCommunicationAcpiTable.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress;
+ CopyMem (&mSmmCommunicationAcpiTable.UefiAcpiDataTable.Identifier, &gEfiSmmCommunicationProtocolGuid, sizeof(gEfiSmmCommunicationProtocolGuid));
+
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ &mSmmCommunicationAcpiTable,
+ sizeof(mSmmCommunicationAcpiTable),
+ &TableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Save context
+ //
+ mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue;
+ mSmmCommunicationContext.BufferPtrAddress = mSmmCommunicationAcpiTable.BufferPtrAddress;
+ SetCommunicationContext ();
+
+ return Status;
+}
diff --git a/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
new file mode 100644
index 0000000000..9b03837cf3
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
@@ -0,0 +1,82 @@
+## @file
+# PI SMM Communication SMM driver that installs the SMM Communication ACPI Table.
+#
+# This SMM driver installs the SMM Communication ACPI Table defined in the UEFI spec
+# which provides a mechanism that can be used in the OS present environment by
+# non-firmware agents for inter-mode communication with SMM agents. It also saves
+# SMM communication context for use by SMM Communication PEIM in the S3 boot mode.
+#
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+ HobLib
+ DebugLib
+ SmmMemLib
+ PcdLib
+
+[Guids]
+ gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiAcpiTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+
+[Ppis]
+ gEfiPeiSmmCommunicationPpiGuid ## UNDEFINED # SMM Configuration Table
+
+[Protocols]
+ gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmCommunicationProtocolGuid ## UNDEFINED # SMM Communication ACPI Table GUID
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES
+
+[Depex]
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiAcpiTableProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ PiSmmCommunicationSmmExtra.uni
diff --git a/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni
new file mode 100644
index 0000000000..55df3905df
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.uni
@@ -0,0 +1,23 @@
+// /** @file
+// PI SMM Communication SMM driver that installs the SMM Communication ACPI Table.
+//
+// This SMM driver installs the SMM Communication ACPI Table defined in the UEFI spec
+// which provides a mechanism that can be used in the OS present environment by
+// non-firmware agents for inter-mode communication with SMM agents. It also saves
+// SMM communication context for use by SMM Communication PEIM in the S3 boot mode.
+//
+// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "PI SMM Communication SMM driver that installs the SMM Communication ACPI Table"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This SMM driver installs the SMM Communication ACPI Table defined in the UEFI Specification, which provides a mechanism that can be used in the OS-present environment by non-firmware agents for inter-mode communication with SMM agents. It also saves an SMM communication context for use by SMM Communication PEIM in the S3 boot mode."
diff --git a/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni
new file mode 100644
index 0000000000..34e7731fb5
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmmExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// PiSmmCommunicationSmm Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"SMM Communication ACPI Table DXE Driver"
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
new file mode 100644
index 0000000000..5e63f8aab2
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
@@ -0,0 +1,512 @@
+/** @file
+Code for Processor S3 restoration
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+typedef struct {
+ UINTN Lock;
+ VOID *StackStart;
+ UINTN StackSize;
+ VOID *ApFunction;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINT32 BufferStart;
+ UINT32 Cr3;
+} MP_CPU_EXCHANGE_INFO;
+
+typedef struct {
+ UINT8 *RendezvousFunnelAddress;
+ UINTN PModeEntryOffset;
+ UINTN FlatJumpOffset;
+ UINTN Size;
+ UINTN LModeEntryOffset;
+ UINTN LongJumpOffset;
+} MP_ASSEMBLY_ADDRESS_MAP;
+
+/**
+ 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)
+
+ACPI_CPU_DATA mAcpiCpuData;
+UINT32 mNumberToFinish;
+MP_CPU_EXCHANGE_INFO *mExchangeInfo;
+BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;
+VOID *mGdtForAp = NULL;
+VOID *mIdtForAp = NULL;
+VOID *mMachineCheckHandlerForAp = NULL;
+MP_MSR_LOCK *mMsrSpinLocks = NULL;
+UINTN mMsrSpinLockCount;
+UINTN mMsrCount = 0;
+
+/**
+ Get MSR spin lock by MSR index.
+
+ @param MsrIndex MSR index value.
+
+ @return Pointer to MSR spin lock.
+
+**/
+SPIN_LOCK *
+GetMsrSpinLockByIndex (
+ IN UINT32 MsrIndex
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < mMsrCount; Index++) {
+ if (MsrIndex == mMsrSpinLocks[Index].MsrIndex) {
+ return mMsrSpinLocks[Index].SpinLock;
+ }
+ }
+ return NULL;
+}
+
+/**
+ Initialize MSR spin lock by MSR index.
+
+ @param MsrIndex MSR index value.
+
+**/
+VOID
+InitMsrSpinLockByIndex (
+ IN UINT32 MsrIndex
+ )
+{
+ UINTN MsrSpinLockCount;
+ UINTN NewMsrSpinLockCount;
+ UINTN Index;
+ UINTN AddedSize;
+
+ if (mMsrSpinLocks == NULL) {
+ MsrSpinLockCount = mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter;
+ mMsrSpinLocks = (MP_MSR_LOCK *) AllocatePool (sizeof (MP_MSR_LOCK) * MsrSpinLockCount);
+ ASSERT (mMsrSpinLocks != NULL);
+ for (Index = 0; Index < MsrSpinLockCount; Index++) {
+ mMsrSpinLocks[Index].SpinLock =
+ (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreMsr.Msr + Index * mSemaphoreSize);
+ mMsrSpinLocks[Index].MsrIndex = (UINT32)-1;
+ }
+ mMsrSpinLockCount = MsrSpinLockCount;
+ mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter = 0;
+ }
+ if (GetMsrSpinLockByIndex (MsrIndex) == NULL) {
+ //
+ // Initialize spin lock for MSR programming
+ //
+ mMsrSpinLocks[mMsrCount].MsrIndex = MsrIndex;
+ InitializeSpinLock (mMsrSpinLocks[mMsrCount].SpinLock);
+ mMsrCount ++;
+ if (mMsrCount == mMsrSpinLockCount) {
+ //
+ // If MSR spin lock buffer is full, enlarge it
+ //
+ AddedSize = SIZE_4KB;
+ mSmmCpuSemaphores.SemaphoreMsr.Msr =
+ AllocatePages (EFI_SIZE_TO_PAGES(AddedSize));
+ ASSERT (mSmmCpuSemaphores.SemaphoreMsr.Msr != NULL);
+ NewMsrSpinLockCount = mMsrSpinLockCount + AddedSize / mSemaphoreSize;
+ mMsrSpinLocks = ReallocatePool (
+ sizeof (MP_MSR_LOCK) * mMsrSpinLockCount,
+ sizeof (MP_MSR_LOCK) * NewMsrSpinLockCount,
+ mMsrSpinLocks
+ );
+ ASSERT (mMsrSpinLocks != NULL);
+ mMsrSpinLockCount = NewMsrSpinLockCount;
+ for (Index = mMsrCount; Index < mMsrSpinLockCount; Index++) {
+ mMsrSpinLocks[Index].SpinLock =
+ (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreMsr.Msr +
+ (Index - mMsrCount) * mSemaphoreSize);
+ mMsrSpinLocks[Index].MsrIndex = (UINT32)-1;
+ }
+ }
+ }
+}
+
+/**
+ 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);
+}
+
+/**
+ Programs registers for the calling processor.
+
+ This function programs registers for the calling processor.
+
+ @param RegisterTable Pointer to register table of the running processor.
+
+**/
+VOID
+SetProcessorRegister (
+ IN CPU_REGISTER_TABLE *RegisterTable
+ )
+{
+ CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
+ UINTN Index;
+ UINTN Value;
+ SPIN_LOCK *MsrSpinLock;
+
+ //
+ // Traverse Register Table of this logical processor
+ //
+ RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry;
+ for (Index = 0; Index < RegisterTable->TableLength; Index++, RegisterTableEntry++) {
+ //
+ // Check the type of specified register
+ //
+ switch (RegisterTableEntry->RegisterType) {
+ //
+ // The specified register is Control Register
+ //
+ case ControlRegister:
+ switch (RegisterTableEntry->Index) {
+ case 0:
+ Value = AsmReadCr0 ();
+ Value = (UINTN) BitFieldWrite64 (
+ Value,
+ RegisterTableEntry->ValidBitStart,
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
+ (UINTN) RegisterTableEntry->Value
+ );
+ AsmWriteCr0 (Value);
+ break;
+ case 2:
+ Value = AsmReadCr2 ();
+ Value = (UINTN) BitFieldWrite64 (
+ Value,
+ RegisterTableEntry->ValidBitStart,
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
+ (UINTN) RegisterTableEntry->Value
+ );
+ AsmWriteCr2 (Value);
+ break;
+ case 3:
+ Value = AsmReadCr3 ();
+ Value = (UINTN) BitFieldWrite64 (
+ Value,
+ RegisterTableEntry->ValidBitStart,
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
+ (UINTN) RegisterTableEntry->Value
+ );
+ AsmWriteCr3 (Value);
+ break;
+ case 4:
+ Value = AsmReadCr4 ();
+ Value = (UINTN) BitFieldWrite64 (
+ Value,
+ RegisterTableEntry->ValidBitStart,
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
+ (UINTN) RegisterTableEntry->Value
+ );
+ AsmWriteCr4 (Value);
+ break;
+ default:
+ break;
+ }
+ break;
+ //
+ // The specified register is Model Specific Register
+ //
+ case Msr:
+ //
+ // 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 {
+ //
+ // Get lock to avoid Package/Core scope MSRs programming issue in parallel execution mode
+ // to make sure MSR read/write operation is atomic.
+ //
+ MsrSpinLock = GetMsrSpinLockByIndex (RegisterTableEntry->Index);
+ AcquireSpinLock (MsrSpinLock);
+ //
+ // Set the bit section according to bit start and length
+ //
+ AsmMsrBitFieldWrite64 (
+ RegisterTableEntry->Index,
+ RegisterTableEntry->ValidBitStart,
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
+ RegisterTableEntry->Value
+ );
+ ReleaseSpinLock (MsrSpinLock);
+ }
+ 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;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ AP initialization before SMBASE relocation in the S3 boot path.
+**/
+VOID
+EarlyMPRendezvousProcedure (
+ VOID
+ )
+{
+ CPU_REGISTER_TABLE *RegisterTableList;
+ UINT32 InitApicId;
+ UINTN Index;
+
+ LoadMtrrData (mAcpiCpuData.MtrrTable);
+
+ //
+ // Find processor number for this CPU.
+ //
+ RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
+ InitApicId = GetInitialApicId ();
+ for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
+ if (RegisterTableList[Index].InitialApicId == InitApicId) {
+ SetProcessorRegister (&RegisterTableList[Index]);
+ break;
+ }
+ }
+
+ //
+ // Count down the number with lock mechanism.
+ //
+ InterlockedDecrement (&mNumberToFinish);
+}
+
+/**
+ AP initialization after SMBASE relocation in the S3 boot path.
+**/
+VOID
+MPRendezvousProcedure (
+ VOID
+ )
+{
+ CPU_REGISTER_TABLE *RegisterTableList;
+ UINT32 InitApicId;
+ UINTN Index;
+
+ ProgramVirtualWireMode ();
+ DisableLvtInterrupts ();
+
+ RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
+ InitApicId = GetInitialApicId ();
+ for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
+ if (RegisterTableList[Index].InitialApicId == InitApicId) {
+ SetProcessorRegister (&RegisterTableList[Index]);
+ break;
+ }
+ }
+
+ //
+ // Count down the number with lock mechanism.
+ //
+ InterlockedDecrement (&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));
+
+ //
+ // Copy AP's GDT, IDT and Machine Check handler from SMRAM to ACPI NVS memory
+ //
+ CopyMem ((VOID *) mExchangeInfo->GdtrProfile.Base, mGdtForAp, mExchangeInfo->GdtrProfile.Limit + 1);
+ CopyMem ((VOID *) mExchangeInfo->IdtrProfile.Base, mIdtForAp, mExchangeInfo->IdtrProfile.Limit + 1);
+ CopyMem ((VOID *)(UINTN) mAcpiCpuData.ApMachineCheckHandlerBase, mMachineCheckHandlerForAp, mAcpiCpuData.ApMachineCheckHandlerSize);
+
+ mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress;
+ mExchangeInfo->StackSize = mAcpiCpuData.StackSize;
+ mExchangeInfo->BufferStart = (UINT32) StartupVector;
+ mExchangeInfo->Cr3 = (UINT32) (AsmReadCr3 ());
+}
+
+/**
+ 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
+EarlyInitializeCpu (
+ VOID
+ )
+{
+ CPU_REGISTER_TABLE *RegisterTableList;
+ UINT32 InitApicId;
+ UINTN Index;
+
+ LoadMtrrData (mAcpiCpuData.MtrrTable);
+
+ //
+ // Find processor number for this CPU.
+ //
+ RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
+ InitApicId = GetInitialApicId ();
+ for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
+ if (RegisterTableList[Index].InitialApicId == InitApicId) {
+ SetProcessorRegister (&RegisterTableList[Index]);
+ break;
+ }
+ }
+
+ ProgramVirtualWireMode ();
+
+ PrepareApStartupVector (mAcpiCpuData.StartupVector);
+
+ mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
+ mExchangeInfo->ApFunction = (VOID *) (UINTN) EarlyMPRendezvousProcedure;
+
+ //
+ // 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
+InitializeCpu (
+ VOID
+ )
+{
+ CPU_REGISTER_TABLE *RegisterTableList;
+ UINT32 InitApicId;
+ UINTN Index;
+
+ RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
+ InitApicId = GetInitialApicId ();
+ for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
+ if (RegisterTableList[Index].InitialApicId == InitApicId) {
+ SetProcessorRegister (&RegisterTableList[Index]);
+ break;
+ }
+ }
+
+ mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
+ //
+ // StackStart was updated when APs were waken up in EarlyInitializeCpu.
+ // Re-initialize StackAddress to original beginning address.
+ //
+ mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress;
+ mExchangeInfo->ApFunction = (VOID *) (UINTN) MPRendezvousProcedure;
+
+ //
+ // Send INIT IPI - SIPI to all APs
+ //
+ SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
+
+ while (mNumberToFinish > 0) {
+ CpuPause ();
+ }
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
new file mode 100644
index 0000000000..40f2a1719d
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
@@ -0,0 +1,486 @@
+/** @file
+Implementation of SMM CPU Services Protocol.
+
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+//
+// SMM CPU Service Protocol instance
+//
+EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = {
+ SmmGetProcessorInfo,
+ SmmSwitchBsp,
+ SmmAddProcessor,
+ SmmRemoveProcessor,
+ SmmWhoAmI,
+ SmmRegisterExceptionHandler
+};
+
+/**
+ Get Package ID/Core ID/Thread ID of a processor.
+
+ APIC ID must be an initial APIC ID.
+
+ The algorithm below 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 ApicId APIC ID of the target logical processor.
+ @param Location Returns the processor location information.
+**/
+VOID
+SmmGetProcessorLocation (
+ IN UINT32 ApicId,
+ OUT EFI_CPU_PHYSICAL_LOCATION *Location
+ )
+{
+ UINTN ThreadBits;
+ UINTN CoreBits;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT32 MaxCpuIdIndex;
+ UINT32 SubIndex;
+ UINTN LevelType;
+ UINT32 MaxLogicProcessorsPerPackage;
+ UINT32 MaxCoresPerPackage;
+ BOOLEAN TopologyLeafSupported;
+
+ ASSERT (Location != NULL);
+
+ ThreadBits = 0;
+ CoreBits = 0;
+ TopologyLeafSupported = FALSE;
+
+ //
+ // Check if the processor is capable of supporting more than one logical processor.
+ //
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
+ ASSERT ((RegEdx & BIT28) != 0);
+
+ //
+ // Assume three-level mapping of APIC ID: Package:Core:SMT.
+ //
+
+ //
+ // Get the max index of basic CPUID
+ //
+ AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
+
+ //
+ // If the extended topology enumeration leaf is available, it
+ // is the preferred mechanism for enumerating topology.
+ //
+ if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
+ AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, 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 ((RegEbx & 0xffff) != 0) {
+ TopologyLeafSupported = TRUE;
+
+ //
+ // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
+ // the SMT sub-field of x2APIC ID.
+ //
+ LevelType = (RegEcx >> 8) & 0xff;
+ ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
+ if ((RegEbx & 0xffff) > 1 ) {
+ ThreadBits = RegEax & 0x1f;
+ } else {
+ //
+ // HT is not supported
+ //
+ ThreadBits = 0;
+ }
+
+ //
+ // 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, &RegEax, NULL, &RegEcx, NULL);
+ LevelType = (RegEcx >> 8) & 0xff;
+ if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
+ CoreBits = (RegEax & 0x1f) - ThreadBits;
+ break;
+ }
+ SubIndex++;
+ } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
+ }
+ }
+
+ if (!TopologyLeafSupported) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
+ MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff;
+ if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
+ AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL);
+ MaxCoresPerPackage = (RegEax >> 26) + 1;
+ } else {
+ //
+ // Must be a single-core processor.
+ //
+ MaxCoresPerPackage = 1;
+ }
+
+ ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
+ CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
+ }
+
+ Location->Thread = ApicId & ~((-1) << ThreadBits);
+ Location->Core = (ApicId >> ThreadBits) & ~((-1) << CoreBits);
+ Location->Package = (ApicId >> (ThreadBits+ CoreBits));
+}
+
+/**
+ 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;
+ SmmGetProcessorLocation ((UINT32)ProcessorId, &gSmmCpuPrivate->ProcessorInfo[Index].Location);
+
+ *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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h
new file mode 100644
index 0000000000..9fe3f45b02
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h
@@ -0,0 +1,181 @@
+/** @file
+Include file for SMM CPU Services protocol implementation.
+
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S
new file mode 100644
index 0000000000..75aa312a6e
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S
@@ -0,0 +1,165 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# MpFuncs.S
+#
+# Abstract:
+#
+# This is the assembly code for Multi-processor S3 support
+#
+#------------------------------------------------------------------------------
+
+.equ VacantFlag, 0x0
+.equ NotVacantFlag, 0xff
+
+.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+.equ StackStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x04
+.equ StackSize, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08
+.equ RendezvousProc, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x0C
+.equ GdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
+.equ IdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16
+.equ BufferStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 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);
+
+ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)
+ASM_PFX(RendezvousFunnelProc):
+RendezvousFunnelProcStart:
+
+# At this point CS = 0x(vv00) and ip= 0x0.
+
+ .byte 0x8c,0xc8 # mov ax, cs
+ .byte 0x8e,0xd8 # mov ds, ax
+ .byte 0x8e,0xc0 # mov es, ax
+ .byte 0x8e,0xd0 # mov ss, ax
+ .byte 0x33,0xc0 # xor ax, ax
+ .byte 0x8e,0xe0 # mov fs, ax
+ .byte 0x8e,0xe8 # mov gs, ax
+
+flat32Start:
+
+ .byte 0xBE
+ .word BufferStart
+ .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
+
+ .byte 0xBE
+ .word GdtrProfile
+ .byte 0x66 # db 66h
+ .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]
+
+ .byte 0xBE
+ .word IdtrProfile
+ .byte 0x66 # db 66h
+ .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]
+
+ .byte 0x33,0xC0 # xor ax, ax
+ .byte 0x8E,0xD8 # mov ds, ax
+
+ .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0
+ .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)
+ .byte 0xF,0x22,0xC0 # mov cr0, eax
+
+FLAT32_JUMP:
+
+ .byte 0x66,0x67,0xEA # far jump
+ .long 0x0 # 32-bit offset
+ .word 0x20 # 16-bit selector
+
+PMODE_ENTRY: # protected mode entry point
+
+ movw $0x8,%ax
+ .byte 0x66
+ movw %ax,%ds
+ .byte 0x66
+ movw %ax,%es
+ .byte 0x66
+ movw %ax,%fs
+ .byte 0x66
+ movw %ax,%gs
+ .byte 0x66
+ movw %ax,%ss # Flat mode setup.
+
+ movl %edx,%esi
+
+ movl %esi,%edi
+ addl $LockLocation, %edi
+ movb $NotVacantFlag, %al
+TestLock:
+ xchgb (%edi), %al
+ cmpb $NotVacantFlag, %al
+ jz TestLock
+
+ProgramStack:
+
+ movl %esi,%edi
+ addl $StackSize, %edi
+ movl (%edi),%eax
+ movl %esi,%edi
+ addl $StackStart, %edi
+ addl (%edi),%eax
+ movl %eax,%esp
+ movl %eax,(%edi)
+
+Releaselock:
+
+ movb $VacantFlag, %al
+ movl %esi,%edi
+ addl $LockLocation, %edi
+ xchgb (%edi), %al
+
+ #
+ # Call assembly function to initialize FPU.
+ #
+ lea ASM_PFX(InitializeFloatingPointUnits), %ebx
+ call *%ebx
+ #
+ # Call C Function
+ #
+ movl %esi,%edi
+ addl $RendezvousProc, %edi
+ movl (%edi),%eax
+
+ testl %eax,%eax
+ jz GoToSleep
+ call *%eax # Call C function
+
+GoToSleep:
+ cli
+ hlt
+ jmp GoToSleep
+
+RendezvousFunnelProcEnd:
+#-------------------------------------------------------------------------------------
+# AsmGetAddressMap (&AddressMap);
+#-------------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmGetAddressMap)
+ASM_PFX(AsmGetAddressMap):
+
+ pushal
+ movl %esp,%ebp
+
+ movl 0x24(%ebp), %ebx
+ movl $RendezvousFunnelProcStart, (%ebx)
+ movl $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x4(%ebx)
+ movl $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x8(%ebx)
+ movl $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x0c(%ebx)
+
+ popal
+ ret
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm
new file mode 100644
index 0000000000..70e24a8270
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm
@@ -0,0 +1,168 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; MpFuncs.asm
+;
+; Abstract:
+;
+; This is the assembly code for Multi-processor S3 support
+;
+;-------------------------------------------------------------------------------
+
+.686p
+.model flat,C
+.code
+
+EXTERN InitializeFloatingPointUnits:PROC
+
+VacantFlag Equ 00h
+NotVacantFlag Equ 0ffh
+
+LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+StackStart equ LockLocation + 4h
+StackSize equ LockLocation + 8h
+RendezvousProc equ LockLocation + 0Ch
+GdtrProfile equ LockLocation + 10h
+IdtrProfile equ LockLocation + 16h
+BufferStart equ LockLocation + 1Ch
+
+;-------------------------------------------------------------------------------------
+;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);
+
+RendezvousFunnelProc PROC near C PUBLIC
+RendezvousFunnelProcStart::
+
+; At this point CS = 0x(vv00) and ip= 0x0.
+
+ db 8ch, 0c8h ; mov ax, cs
+ db 8eh, 0d8h ; mov ds, ax
+ db 8eh, 0c0h ; mov es, ax
+ db 8eh, 0d0h ; mov ss, ax
+ db 33h, 0c0h ; xor ax, ax
+ db 8eh, 0e0h ; mov fs, ax
+ db 8eh, 0e8h ; mov gs, ax
+
+flat32Start::
+
+ db 0BEh
+ dw BufferStart ; mov si, BufferStart
+ db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
+
+ db 0BEh
+ dw GdtrProfile ; mov si, GdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh
+ dw IdtrProfile ; mov si, IdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 33h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
+ db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+FLAT32_JUMP::
+
+ db 66h, 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 20h ; 16-bit selector
+
+PMODE_ENTRY:: ; protected mode entry point
+
+ mov ax, 8h
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax ; Flat mode setup.
+
+ mov esi, edx
+
+ mov edi, esi
+ add edi, LockLocation
+ mov al, NotVacantFlag
+TestLock::
+ xchg byte ptr [edi], al
+ cmp al, NotVacantFlag
+ jz TestLock
+
+ProgramStack::
+
+ mov edi, esi
+ add edi, StackSize
+ mov eax, dword ptr [edi]
+ mov edi, esi
+ add edi, StackStart
+ add eax, dword ptr [edi]
+ mov esp, eax
+ mov dword ptr [edi], eax
+
+Releaselock::
+
+ mov al, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg byte ptr [edi], al
+
+ ;
+ ; Call assembly function to initialize FPU.
+ ;
+ mov ebx, InitializeFloatingPointUnits
+ call ebx
+ ;
+ ; Call C Function
+ ;
+ mov edi, esi
+ add edi, RendezvousProc
+ mov eax, dword ptr [edi]
+
+ test eax, eax
+ jz GoToSleep
+ call eax ; Call C function
+
+GoToSleep::
+ cli
+ hlt
+ jmp $-2
+
+RendezvousFunnelProc ENDP
+RendezvousFunnelProcEnd::
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+AsmGetAddressMap PROC near C PUBLIC
+
+ pushad
+ mov ebp,esp
+
+ mov ebx, dword ptr [ebp+24h]
+ mov dword ptr [ebx], RendezvousFunnelProcStart
+ mov dword ptr [ebx+4h], PMODE_ENTRY - RendezvousFunnelProcStart
+ mov dword ptr [ebx+8h], FLAT32_JUMP - RendezvousFunnelProcStart
+ mov dword ptr [ebx+0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+
+ popad
+ ret
+
+AsmGetAddressMap ENDP
+
+END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
new file mode 100644
index 0000000000..a871bef4e2
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -0,0 +1,130 @@
+/** @file
+Page table manipulation functions for IA-32 processors
+
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+/**
+ Create PageTable for SMM use.
+
+ @return PageTable Address
+
+**/
+UINT32
+SmmInitPageTable (
+ VOID
+ )
+{
+ UINTN PageFaultHandlerHookAddress;
+ IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
+
+ //
+ // Initialize spin lock
+ //
+ InitializeSpinLock (mPFLock);
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ //
+ // 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
+ //
+ SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler);
+ }
+
+ //
+ // Additional SMM IDT initialization for SMM stack guard
+ //
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ InitializeIDTSmmStackGuard ();
+ }
+ return Gen4GPageTable (0, 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;
+
+ ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
+
+ AcquireSpinLock (mPFLock);
+
+ PFAddress = AsmReadCr2 ();
+
+ if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
+ (PFAddress >= mCpuHotPlugData.SmrrBase) &&
+ (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
+ DEBUG ((EFI_D_ERROR, "SMM stack overflow!\n"));
+ CpuDeadLoop ();
+ }
+
+ //
+ // If a page fault occurs in SMM range
+ //
+ if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
+ (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
+ if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {
+ DEBUG ((EFI_D_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 ();
+ }
+ }
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ SmmProfilePFHandler (
+ SystemContext.SystemContextIa32->Eip,
+ SystemContext.SystemContextIa32->ExceptionData
+ );
+ } else {
+ SmiDefaultPFHandler ();
+ }
+
+ ReleaseSpinLock (mPFLock);
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c
new file mode 100644
index 0000000000..02a866b430
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c
@@ -0,0 +1,48 @@
+/** @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.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
new file mode 100644
index 0000000000..ec5b9a0b04
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
@@ -0,0 +1,169 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmiEntry.S
+#
+# Abstract:
+#
+# Code template of the SMI handler for a particular processor
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)
+ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
+ASM_GLOBAL ASM_PFX(gSmiCr3)
+ASM_GLOBAL ASM_PFX(gSmiStack)
+ASM_GLOBAL ASM_PFX(gSmbase)
+ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
+ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
+
+.equ DSC_OFFSET, 0xfb00
+.equ DSC_GDTPTR, 0x30
+.equ DSC_GDTSIZ, 0x38
+.equ DSC_CS, 14
+.equ DSC_DS, 16
+.equ DSC_SS, 18
+.equ DSC_OTHERSEG, 20
+
+.equ PROTECT_MODE_CS, 0x08
+.equ PROTECT_MODE_DS, 0x20
+.equ TSS_SEGMENT, 0x40
+
+ .text
+
+ASM_PFX(gcSmiHandlerTemplate):
+
+_SmiEntryPoint:
+ .byte 0xbb # mov bx, imm16
+ .word _GdtDesc - _SmiEntryPoint + 0x8000
+ .byte 0x2e,0xa1 # mov ax, cs:[offset16]
+ .word DSC_OFFSET + DSC_GDTSIZ
+ decl %eax
+ movl %eax, %cs:(%edi) # mov cs:[bx], ax
+ .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
+ .word DSC_OFFSET + DSC_GDTPTR
+ movw %ax, %cs:2(%edi)
+ movw %ax, %bp # ebp = GDT base
+ .byte 0x66
+ lgdt %cs:(%edi)
+# Patch ProtectedMode Segment
+ .byte 0xb8 # mov ax, imm16
+ .word PROTECT_MODE_CS # set AX for segment directly
+ movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax
+# Patch ProtectedMode entry
+ .byte 0x66, 0xbf # mov edi, SMBASE
+ASM_PFX(gSmbase): .space 4
+ .byte 0x67
+ lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
+ movw %ax, %cs:-6(%edi)
+ movl %cr0, %ebx
+ .byte 0x66
+ andl $0x9ffafff3, %ebx
+ .byte 0x66
+ orl $0x23, %ebx
+ movl %ebx, %cr0
+ .byte 0x66,0xea
+ .space 4
+ .space 2
+_GdtDesc: .space 4
+ .space 2
+
+Start32bit:
+ movw $PROTECT_MODE_DS, %ax
+ movl %eax,%ds
+ movl %eax,%es
+ movl %eax,%fs
+ movl %eax,%gs
+ movl %eax,%ss
+ .byte 0xbc # mov esp, imm32
+ASM_PFX(gSmiStack): .space 4
+ movl $ASM_PFX(gSmiHandlerIdtr), %eax
+ lidt (%eax)
+ jmp ProtFlatMode
+
+ProtFlatMode:
+ .byte 0xb8 # mov eax, imm32
+ASM_PFX(gSmiCr3): .space 4
+ movl %eax, %cr3
+#
+# Need to test for CR4 specific bit support
+#
+ movl $1, %eax
+ cpuid # use CPUID to determine if specific CR4 bits are supported
+ xorl %eax, %eax # Clear EAX
+ testl $BIT2, %edx # Check for DE capabilities
+ jz L8
+ orl $BIT3, %eax
+L8:
+ testl $BIT6, %edx # Check for PAE capabilities
+ jz L9
+ orl $BIT5, %eax
+L9:
+ testl $BIT7, %edx # Check for MCE capabilities
+ jz L10
+ orl $BIT6, %eax
+L10:
+ testl $BIT24, %edx # Check for FXSR capabilities
+ jz L11
+ orl $BIT9, %eax
+L11:
+ testl $BIT25, %edx # Check for SSE capabilities
+ jz L12
+ orl $BIT10, %eax
+L12: # as cr4.PGE is not set here, refresh cr3
+ movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
+ movl %cr0, %ebx
+ orl $0x080010000, %ebx # enable paging + WP
+ movl %ebx, %cr0
+ leal DSC_OFFSET(%edi),%ebx
+ movw DSC_DS(%ebx),%ax
+ movl %eax, %ds
+ movw DSC_OTHERSEG(%ebx),%ax
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movw DSC_SS(%ebx),%ax
+ movl %eax, %ss
+
+ cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
+ jz L5
+
+# Load TSS
+ movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
+ movl $TSS_SEGMENT, %eax
+ ltrw %ax
+L5:
+
+# jmp _SmiHandler # instruction is not needed
+
+_SmiHandler:
+ movl (%esp), %ebx
+
+ pushl %ebx
+ movl $ASM_PFX(CpuSmmDebugEntry), %eax
+ call *%eax
+ popl %ecx
+
+ pushl %ebx
+ movl $ASM_PFX(SmiRendezvous), %eax
+ call *%eax
+ popl %ecx
+
+ pushl %ebx
+ movl $ASM_PFX(CpuSmmDebugExit), %eax
+ call *%eax
+ popl %ecx
+
+ rsm
+
+ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm
new file mode 100644
index 0000000000..ac1a9b48dd
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm
@@ -0,0 +1,177 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmiEntry.asm
+;
+; Abstract:
+;
+; Code template of the SMI handler for a particular processor
+;
+;-------------------------------------------------------------------------------
+
+ .686p
+ .model flat,C
+ .xmm
+
+DSC_OFFSET EQU 0fb00h
+DSC_GDTPTR EQU 30h
+DSC_GDTSIZ EQU 38h
+DSC_CS EQU 14
+DSC_DS EQU 16
+DSC_SS EQU 18
+DSC_OTHERSEG EQU 20
+
+PROTECT_MODE_CS EQU 08h
+PROTECT_MODE_DS EQU 20h
+TSS_SEGMENT EQU 40h
+
+SmiRendezvous PROTO C
+CpuSmmDebugEntry PROTO C
+CpuSmmDebugExit PROTO C
+
+EXTERNDEF gcSmiHandlerTemplate:BYTE
+EXTERNDEF gcSmiHandlerSize:WORD
+EXTERNDEF gSmiCr3:DWORD
+EXTERNDEF gSmiStack:DWORD
+EXTERNDEF gSmbase:DWORD
+EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
+EXTERNDEF gSmiHandlerIdtr:FWORD
+
+ .code
+
+gcSmiHandlerTemplate LABEL BYTE
+
+_SmiEntryPoint:
+ DB 0bbh ; mov bx, imm16
+ DW offset _GdtDesc - _SmiEntryPoint + 8000h
+ DB 2eh, 0a1h ; mov ax, cs:[offset16]
+ DW DSC_OFFSET + DSC_GDTSIZ
+ dec eax
+ mov cs:[edi], eax ; mov cs:[bx], ax
+ DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
+ DW DSC_OFFSET + DSC_GDTPTR
+ mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax
+ mov bp, ax ; ebp = GDT base
+ DB 66h
+ lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]
+; Patch ProtectedMode Segment
+ DB 0b8h ; mov ax, imm16
+ DW PROTECT_MODE_CS ; set AX for segment directly
+ mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax
+; Patch ProtectedMode entry
+ DB 66h, 0bfh ; mov edi, SMBASE
+gSmbase DD ?
+ DB 67h
+ lea ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]
+ mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax
+ mov ebx, cr0
+ DB 66h
+ and ebx, 9ffafff3h
+ DB 66h
+ or ebx, 23h
+ mov cr0, ebx
+ DB 66h, 0eah
+ DD ?
+ DW ?
+_GdtDesc FWORD ?
+
+@32bit:
+ mov ax, PROTECT_MODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ DB 0bch ; mov esp, imm32
+gSmiStack DD ?
+ mov eax, offset gSmiHandlerIdtr
+ lidt fword ptr [eax]
+ jmp ProtFlatMode
+
+ProtFlatMode:
+ DB 0b8h ; mov eax, imm32
+gSmiCr3 DD ?
+ 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 @f
+ or eax, BIT3
+@@:
+ test edx, BIT6 ; Check for PAE capabilities
+ jz @f
+ or eax, BIT5
+@@:
+ test edx, BIT7 ; Check for MCE capabilities
+ jz @f
+ or eax, BIT6
+@@:
+ test edx, BIT24 ; Check for FXSR capabilities
+ jz @f
+ or eax, BIT9
+@@:
+ test edx, BIT25 ; Check for SSE capabilities
+ jz @f
+ or eax, BIT10
+@@: ; as cr4.PGE is not set here, refresh cr3
+ mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
+ mov ebx, cr0
+ or ebx, 080010000h ; enable paging + WP
+ 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
+
+ cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0
+ jz @F
+
+; Load TSS
+ mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag
+ mov eax, TSS_SEGMENT
+ ltr ax
+@@:
+; jmp _SmiHandler ; instruction is not needed
+
+_SmiHandler PROC
+ mov ebx, [esp] ; CPU Index
+
+ push ebx
+ mov eax, CpuSmmDebugEntry
+ call eax
+ pop ecx
+
+ push ebx
+ mov eax, SmiRendezvous
+ call eax
+ pop ecx
+
+ push ebx
+ mov eax, CpuSmmDebugExit
+ call eax
+ pop ecx
+
+ rsm
+_SmiHandler ENDP
+
+gcSmiHandlerSize DW $ - _SmiEntryPoint
+
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S
new file mode 100644
index 0000000000..4130bf5be5
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S
@@ -0,0 +1,911 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmiException.S
+#
+# Abstract:
+#
+# Exception handlers used in SM mode
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(SmiPFHandler)
+ASM_GLOBAL ASM_PFX(PageFaultStubFunction)
+ASM_GLOBAL ASM_PFX(gSmiMtrrs)
+ASM_GLOBAL ASM_PFX(gcSmiIdtr)
+ASM_GLOBAL ASM_PFX(gcSmiGdtr)
+ASM_GLOBAL ASM_PFX(gcPsd)
+ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))
+
+ .data
+
+NullSeg: .quad 0 # reserved by architecture
+CodeSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+ProtModeCodeSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+ProtModeSsSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x93
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+DataSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x93
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+CodeSeg16:
+ .word -1
+ .word 0
+ .byte 0
+ .byte 0x9b
+ .byte 0x8f
+ .byte 0
+DataSeg16:
+ .word -1
+ .word 0
+ .byte 0
+ .byte 0x93
+ .byte 0x8f
+ .byte 0
+CodeSeg64:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xaf # LimitHigh
+ .byte 0 # BaseHigh
+.equ GDT_SIZE, .- NullSeg
+
+TssSeg:
+ .word TSS_DESC_SIZE -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x89
+ .byte 0x00 # LimitHigh
+ .byte 0 # BaseHigh
+ExceptionTssSeg:
+ .word TSS_DESC_SIZE - 1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x89
+ .byte 0x00 # LimitHigh
+ .byte 0 # BaseHigh
+
+.equ CODE_SEL, CodeSeg32 - NullSeg
+.equ DATA_SEL, DataSeg32 - NullSeg
+.equ TSS_SEL, TssSeg - NullSeg
+.equ EXCEPTION_TSS_SEL, ExceptionTssSeg - NullSeg
+
+# IA32 TSS fields
+.equ TSS_ESP0, 4
+.equ TSS_SS0, 8
+.equ TSS_ESP1, 12
+.equ TSS_SS1, 16
+.equ TSS_ESP2, 20
+.equ TSS_SS2, 24
+.equ TSS_CR3, 28
+.equ TSS_EIP, 32
+.equ TSS_EFLAGS, 36
+.equ TSS_EAX, 40
+.equ TSS_ECX, 44
+.equ TSS_EDX, 48
+.equ TSS_EBX, 52
+.equ TSS_ESP, 56
+.equ TSS_EBP, 60
+.equ TSS_ESI, 64
+.equ TSS_EDI, 68
+.equ TSS_ES, 72
+.equ TSS_CS, 76
+.equ TSS_SS, 80
+.equ TSS_DS, 84
+.equ TSS_FS, 88
+.equ TSS_GS, 92
+.equ TSS_LDT, 96
+
+# Create 2 TSS segments just after GDT
+TssDescriptor:
+ .word 0 # PreviousTaskLink
+ .word 0 # Reserved
+ .long 0 # ESP0
+ .word 0 # SS0
+ .word 0 # Reserved
+ .long 0 # ESP1
+ .word 0 # SS1
+ .word 0 # Reserved
+ .long 0 # ESP2
+ .word 0 # SS2
+ .word 0 # Reserved
+ .long 0 # CR3
+ .long 0 # EIP
+ .long 0 # EFLAGS
+ .long 0 # EAX
+ .long 0 # ECX
+ .long 0 # EDX
+ .long 0 # EBX
+ .long 0 # ESP
+ .long 0 # EBP
+ .long 0 # ESI
+ .long 0 # EDI
+ .word 0 # ES
+ .word 0 # Reserved
+ .word 0 # CS
+ .word 0 # Reserved
+ .word 0 # SS
+ .word 0 # Reserved
+ .word 0 # DS
+ .word 0 # Reserved
+ .word 0 # FS
+ .word 0 # Reserved
+ .word 0 # GS
+ .word 0 # Reserved
+ .word 0 # LDT Selector
+ .word 0 # Reserved
+ .word 0 # T
+ .word 0 # I/O Map Base
+.equ TSS_DESC_SIZE, . - TssDescriptor
+
+ExceptionTssDescriptor:
+ .word 0 # PreviousTaskLink
+ .word 0 # Reserved
+ .long 0 # ESP0
+ .word 0 # SS0
+ .word 0 # Reserved
+ .long 0 # ESP1
+ .word 0 # SS1
+ .word 0 # Reserved
+ .long 0 # ESP2
+ .word 0 # SS2
+ .word 0 # Reserved
+ .long 0 # CR3
+ .long PFHandlerEntry # EIP
+ .long 00000002 # EFLAGS
+ .long 0 # EAX
+ .long 0 # ECX
+ .long 0 # EDX
+ .long 0 # EBX
+ .long 0 # ESP
+ .long 0 # EBP
+ .long 0 # ESI
+ .long 0 # EDI
+ .word DATA_SEL # ES
+ .word 0 # Reserved
+ .word CODE_SEL # CS
+ .word 0 # Reserved
+ .word DATA_SEL # SS
+ .word 0 # Reserved
+ .word DATA_SEL # DS
+ .word 0 # Reserved
+ .word DATA_SEL # FS
+ .word 0 # Reserved
+ .word DATA_SEL # GS
+ .word 0 # Reserved
+ .word 0 # LDT Selector
+ .word 0 # Reserved
+ .word 0 # T
+ .word 0 # I/O Map Base
+
+ASM_PFX(gcPsd):
+ .ascii "PSDSIG "
+ .word PSD_SIZE
+ .word 2
+ .word 1 << 2
+ .word CODE_SEL
+ .word DATA_SEL
+ .word DATA_SEL
+ .word DATA_SEL
+ .word 0
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .quad 0
+ .long NullSeg
+ .long 0
+ .long GDT_SIZE
+ .long 0
+ .space 24, 0
+ .long ASM_PFX(gSmiMtrrs)
+ .long 0
+.equ PSD_SIZE, . - ASM_PFX(gcPsd)
+
+ASM_PFX(gcSmiGdtr): .word GDT_SIZE - 1
+ .long NullSeg
+
+ASM_PFX(gcSmiIdtr): .word IDT_SIZE - 1
+ .long _SmiIDT
+
+_SmiIDT:
+# The following segment repeats 32 times:
+# No. 1
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 2
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 3
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 4
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 5
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 6
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 7
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 8
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 9
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 10
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 11
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 12
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 13
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 14
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 15
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 16
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 17
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 18
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 19
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 20
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 21
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 22
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 23
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 24
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 25
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 26
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 27
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 28
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 29
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 30
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 31
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+# No. 32
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+
+.equ IDT_SIZE, . - _SmiIDT
+
+TaskGateDescriptor:
+ .word 0 # Reserved
+ .word EXCEPTION_TSS_SEL # TSS Segment selector
+ .byte 0 # Reserved
+ .byte 0x85 # Task Gate, present, DPL = 0
+ .word 0 # Reserved
+
+ .text
+
+#------------------------------------------------------------------------------
+# PageFaultIdtHandlerSmmProfile is the entry point for all exceptions
+#
+# Stack:
+#+---------------------+
+#+ EFlags +
+#+---------------------+
+#+ CS +
+#+---------------------+
+#+ EIP +
+#+---------------------+
+#+ Error Code +
+#+---------------------+
+#+ Vector Number +
+#+---------------------+
+#+ EBP +
+#+---------------------+ <-- EBP
+#
+# RSP set to odd multiple of 8 means ErrCode PRESENT
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
+ASM_PFX(PageFaultIdtHandlerSmmProfile):
+ pushl $0x0e # Page Fault
+ pushl %ebp
+ movl %esp, %ebp
+
+
+ #
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ # is 16-byte aligned
+ #
+ andl $0xfffffff0, %esp
+ subl $12, %esp
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ pushl %ebx
+ leal (6*4)(%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 (4*4)(%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 (3*4)(%ebp), %eax
+ pushl %eax
+
+## UINT32 Gdtr[2], Idtr[2];
+ subl $8, %esp
+ sidt (%esp)
+ movl 2(%esp), %eax
+ xchgl (%esp), %eax
+ andl $0xffff, %eax
+ movl %eax, 4(%esp)
+
+ subl $8, %esp
+ sgdt (%esp)
+ movl 2(%esp), %eax
+ xchgl (%esp), %eax
+ andl $0xffff, %eax
+ movl %eax, 4(%esp)
+
+## UINT32 Ldtr, Tr;
+ xorl %eax, %eax
+ strw %ax
+ pushl %eax
+ sldtw %ax
+ pushl %eax
+
+## UINT32 EFlags;
+ movl (5*4)(%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, 0xae, 0x07 #fxsave [edi]
+
+# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
+ cld
+
+## UINT32 ExceptionData;
+ pushl (2*4)(%ebp)
+
+## call into exception handler
+
+## Prepare parameter and call
+ movl %esp, %edx
+ pushl %edx
+ movl (1*4)(%ebp), %edx
+ pushl %edx
+
+ #
+ # Call External Exception Handler
+ #
+ movl $ASM_PFX(SmiPFHandler), %eax
+ call *%eax
+ addl $8, %esp
+ jmp L4
+
+L4:
+## UINT32 ExceptionData;
+ addl $4, %esp
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ movl %esp, %esi
+ .byte 0xf, 0xae, 0xe # fxrstor [esi]
+ addl $512, %esp
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+## Skip restoration of DRx registers to support debuggers
+## that set breakpoints in interrupt/exception context
+ addl $4*6, %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 (5*4)(%ebp)
+
+## UINT32 Ldtr, Tr;
+## UINT32 Gdtr[2], Idtr[2];
+## Best not let anyone mess with these particular registers...
+ addl $24, %esp
+
+## UINT32 Eip;
+ popl (3*4)(%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 (4*4)(%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
+
+# Enable TF bit after page fault handler runs
+ btsl $8, 16(%esp) # EFLAGS
+
+ addl $8, %esp # skip INT# & ErrCode
+Return:
+ iret
+#
+# Page Fault Exception Handler entry when SMM Stack Guard is enabled
+# Executiot starts here after a task switch
+#
+PFHandlerEntry:
+#
+# Get this processor's TSS
+#
+ subl $8, %esp
+ sgdt 2(%esp)
+ movl 4(%esp), %eax # GDT base
+ addl $8, %esp
+ movl (TSS_SEL+2)(%eax), %ecx
+ shll $8, %ecx
+ movb (TSS_SEL+7)(%eax), %cl
+ rorl $8, %ecx # ecx = TSS base
+
+ movl %esp, %ebp
+
+ #
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ # is 16-byte aligned
+ #
+ andl $0xfffffff0, %esp
+ subl $12, %esp
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pushl TSS_EAX(%ecx)
+ pushl TSS_ECX(%ecx)
+ pushl TSS_EDX(%ecx)
+ pushl TSS_EBX(%ecx)
+ pushl TSS_ESP(%ecx)
+ pushl TSS_EBP(%ecx)
+ pushl TSS_ESI(%ecx)
+ pushl TSS_EDI(%ecx)
+
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ movzwl TSS_SS(%ecx), %eax
+ pushl %eax
+ movzwl TSS_CS(%ecx), %eax
+ pushl %eax
+ movzwl TSS_DS(%ecx), %eax
+ pushl %eax
+ movzwl TSS_ES(%ecx), %eax
+ pushl %eax
+ movzwl TSS_FS(%ecx), %eax
+ pushl %eax
+ movzwl TSS_GS(%ecx), %eax
+ pushl %eax
+
+## UINT32 Eip;
+ pushl TSS_EIP(%ecx)
+
+## UINT32 Gdtr[2], Idtr[2];
+ subl $8, %esp
+ sidt (%esp)
+ movl 2(%esp), %eax
+ xchgl (%esp), %eax
+ andl $0xFFFF, %eax
+ movl %eax, 4(%esp)
+
+ subl $8, %esp
+ sgdt (%esp)
+ movl 2(%esp), %eax
+ xchgl (%esp), %eax
+ andl $0xFFFF, %eax
+ movl %eax, 4(%esp)
+
+## UINT32 Ldtr, Tr;
+ movl $TSS_SEL, %eax
+ pushl %eax
+ movzwl TSS_LDT(%ecx), %eax
+ pushl %eax
+
+## UINT32 EFlags;
+ pushl TSS_EFLAGS(%ecx)
+
+## 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;
+## Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
+## when executing fxsave/fxrstor instruction
+ clts
+ subl $512, %esp
+ movl %esp, %edi
+ .byte 0x0f, 0xae, 0x07 #fxsave [edi]
+
+# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
+ cld
+
+## UINT32 ExceptionData;
+ pushl (%ebp)
+
+## call into exception handler
+ movl %ecx, %ebx
+ movl $ASM_PFX(SmiPFHandler), %eax
+
+## Prepare parameter and call
+ movl %esp, %edx
+ pushl %edx
+ movl $14, %edx
+ pushl %edx
+
+ #
+ # Call External Exception Handler
+ #
+ call *%eax
+ addl $8, %esp
+
+ movl %ebx, %ecx
+## UINT32 ExceptionData;
+ addl $4, %esp
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ movl %esp, %esi
+ .byte 0xf, 0xae, 0xe # fxrstor [esi]
+ addl $512, %esp
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+## Skip restoration of DRx registers to support debuggers
+## that set breakpoints in interrupt/exception context
+ addl $4*6, %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, TSS_CR3(%ecx)
+ popl %eax
+ movl %eax, %cr4
+
+## UINT32 EFlags;
+ popl TSS_EFLAGS(%ecx)
+
+## UINT32 Ldtr, Tr;
+## UINT32 Gdtr[2], Idtr[2];
+## Best not let anyone mess with these particular registers...
+ addl $24, %esp
+
+## UINT32 Eip;
+ popl TSS_EIP(%ecx)
+
+## 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 %eax
+ movw %ax, TSS_GS(%ecx)
+ popl %eax
+ movw %ax, TSS_FS(%ecx)
+ popl %eax
+ movw %ax, TSS_ES(%ecx)
+ popl %eax
+ movw %ax, TSS_DS(%ecx)
+ popl %eax
+ movw %ax, TSS_CS(%ecx)
+ popl %eax
+ movw %ax, TSS_SS(%ecx)
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ popl TSS_EDI(%ecx)
+ popl TSS_ESI(%ecx)
+ addl $4, %esp # not for ebp
+ addl $4, %esp # not for esp
+ popl TSS_EBX(%ecx)
+ popl TSS_EDX(%ecx)
+ popl TSS_ECX(%ecx)
+ popl TSS_EAX(%ecx)
+
+ movl %ebp, %esp
+
+# Set single step DB# if SMM profile is enabled and page fault exception happens
+ cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))
+ jz Done2
+# Create return context for iret in stub function
+ movl TSS_ESP(%ecx), %eax # Get old stack pointer
+ movl TSS_EIP(%ecx), %ebx
+ movl %ebx, -0xc(%eax) # create EIP in old stack
+ movzwl TSS_CS(%ecx), %ebx
+ movl %ebx, -0x8(%eax) # create CS in old stack
+ movl TSS_EFLAGS(%ecx), %ebx
+ btsl $8,%ebx
+ movl %ebx, -0x4(%eax) # create eflags in old stack
+ movl TSS_ESP(%ecx), %eax # Get old stack pointer
+ subl $12, %eax # minus 12 byte
+ movl %eax, TSS_ESP(%ecx) # Set new stack pointer
+
+# Replace the EIP of interrupted task with stub function
+ movl $ASM_PFX(PageFaultStubFunction), %eax
+ movl %eax, TSS_EIP(%ecx)
+# Jump to the iret so next page fault handler as a task will start again after iret.
+
+Done2:
+
+ addl $4, %esp # skip ErrCode
+
+ jmp Return
+
+ASM_PFX(PageFaultStubFunction):
+#
+# we need clean TS bit in CR0 to execute
+# x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
+#
+ clts
+ iret
+
+ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
+ASM_PFX(InitializeIDTSmmStackGuard):
+ pushl %ebx
+#
+# 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 ran out.
+#
+ leal _SmiIDT + 14 * 8, %ebx
+ leal TaskGateDescriptor, %edx
+ movl (%edx), %eax
+ movl %eax, (%ebx)
+ movl 4(%edx), %eax
+ movl %eax, 4(%ebx)
+
+ popl %ebx
+ ret
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
new file mode 100644
index 0000000000..b4eb492da0
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
@@ -0,0 +1,738 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmiException.asm
+;
+; Abstract:
+;
+; Exception handlers used in SM mode
+;
+;-------------------------------------------------------------------------------
+
+ .686p
+ .model flat,C
+
+EXTERNDEF SmiPFHandler:PROC
+EXTERNDEF PageFaultStubFunction:PROC
+EXTERNDEF gSmiMtrrs:QWORD
+EXTERNDEF gcSmiIdtr:FWORD
+EXTERNDEF gcSmiGdtr:FWORD
+EXTERNDEF gcPsd:BYTE
+EXTERNDEF FeaturePcdGet (PcdCpuSmmProfileEnable):BYTE
+
+
+ .data
+
+NullSeg DQ 0 ; reserved by architecture
+CodeSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+ProtModeCodeSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+ProtModeSsSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 93h
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+DataSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 93h
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+CodeSeg16 LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 9bh
+ DB 8fh
+ DB 0
+DataSeg16 LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 93h
+ DB 8fh
+ DB 0
+CodeSeg64 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0afh ; LimitHigh
+ DB 0 ; BaseHigh
+GDT_SIZE = $ - offset NullSeg
+
+TssSeg LABEL QWORD
+ DW TSS_DESC_SIZE - 1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 89h
+ DB 00h ; LimitHigh
+ DB 0 ; BaseHigh
+ExceptionTssSeg LABEL QWORD
+ DW TSS_DESC_SIZE - 1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 89h
+ DB 00h ; LimitHigh
+ DB 0 ; BaseHigh
+
+CODE_SEL = offset CodeSeg32 - offset NullSeg
+DATA_SEL = offset DataSeg32 - offset NullSeg
+TSS_SEL = offset TssSeg - offset NullSeg
+EXCEPTION_TSS_SEL = offset ExceptionTssSeg - offset NullSeg
+
+IA32_TSS STRUC
+ DW ?
+ DW ?
+ ESP0 DD ?
+ SS0 DW ?
+ DW ?
+ ESP1 DD ?
+ SS1 DW ?
+ DW ?
+ ESP2 DD ?
+ SS2 DW ?
+ DW ?
+ _CR3 DD ?
+ EIP DD ?
+ EFLAGS DD ?
+ _EAX DD ?
+ _ECX DD ?
+ _EDX DD ?
+ _EBX DD ?
+ _ESP DD ?
+ _EBP DD ?
+ _ESI DD ?
+ _EDI DD ?
+ _ES DW ?
+ DW ?
+ _CS DW ?
+ DW ?
+ _SS DW ?
+ DW ?
+ _DS DW ?
+ DW ?
+ _FS DW ?
+ DW ?
+ _GS DW ?
+ DW ?
+ LDT DW ?
+ DW ?
+ DW ?
+ DW ?
+IA32_TSS ENDS
+
+; Create 2 TSS segments just after GDT
+TssDescriptor LABEL BYTE
+ 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 = $ - offset TssDescriptor
+
+ExceptionTssDescriptor LABEL BYTE
+ 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 offset 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
+
+gcPsd LABEL BYTE
+ DB 'PSDSIG '
+ DW PSD_SIZE
+ DW 2
+ DW 1 SHL 2
+ DW CODE_SEL
+ DW DATA_SEL
+ DW DATA_SEL
+ DW DATA_SEL
+ DW 0
+ DQ 0
+ DQ 0
+ DQ 0
+ DQ offset NullSeg
+ DD GDT_SIZE
+ DD 0
+ DB 24 dup (0)
+ DQ offset gSmiMtrrs
+PSD_SIZE = $ - offset gcPsd
+
+gcSmiGdtr LABEL FWORD
+ DW GDT_SIZE - 1
+ DD offset NullSeg
+
+gcSmiIdtr LABEL FWORD
+ DW IDT_SIZE - 1
+ DD offset _SmiIDT
+
+_SmiIDT LABEL QWORD
+REPEAT 32
+ DW 0 ; Offset 0:15
+ DW CODE_SEL ; Segment selector
+ DB 0 ; Unused
+ DB 8eh ; Interrupt Gate, Present
+ DW 0 ; Offset 16:31
+ ENDM
+IDT_SIZE = $ - offset _SmiIDT
+
+TaskGateDescriptor LABEL DWORD
+ DW 0 ; Reserved
+ DW EXCEPTION_TSS_SEL ; TSS Segment selector
+ DB 0 ; Reserved
+ DB 85h ; Task Gate, present, DPL = 0
+ DW 0 ; Reserved
+
+
+ .code
+;------------------------------------------------------------------------------
+; PageFaultIdtHandlerSmmProfile is the entry point page fault only
+;
+;
+; Stack:
+; +---------------------+
+; + EFlags +
+; +---------------------+
+; + CS +
+; +---------------------+
+; + EIP +
+; +---------------------+
+; + Error Code +
+; +---------------------+
+; + Vector Number +
+; +---------------------+
+; + EBP +
+; +---------------------+ <-- EBP
+;
+;
+;------------------------------------------------------------------------------
+PageFaultIdtHandlerSmmProfile PROC
+ push 0eh ; 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, 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
+
+;; Prepare parameter and call
+ mov edx, esp
+ push edx
+ mov edx, dword ptr [ebp + 1 * 4]
+ push edx
+
+ ;
+ ; Call External Exception Handler
+ ;
+ mov eax, SmiPFHandler
+ call eax
+ add esp, 8
+
+;; 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 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 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
+
+; Enable TF bit after page fault handler runs
+ bts dword ptr [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, 0fffffff0h
+ sub esp, 12
+
+;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ push (IA32_TSS ptr [ecx])._EAX
+ push (IA32_TSS ptr [ecx])._ECX
+ push (IA32_TSS ptr [ecx])._EDX
+ push (IA32_TSS ptr [ecx])._EBX
+ push (IA32_TSS ptr [ecx])._ESP
+ push (IA32_TSS ptr [ecx])._EBP
+ push (IA32_TSS ptr [ecx])._ESI
+ push (IA32_TSS ptr [ecx])._EDI
+
+;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ movzx eax, (IA32_TSS ptr [ecx])._SS
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx])._CS
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx])._DS
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx])._ES
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx])._FS
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx])._GS
+ push eax
+
+;; UINT32 Eip;
+ push (IA32_TSS ptr [ecx]).EIP
+
+;; 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;
+ mov eax, TSS_SEL
+ push eax
+ movzx eax, (IA32_TSS ptr [ecx]).LDT
+ push eax
+
+;; UINT32 EFlags;
+ push (IA32_TSS ptr [ecx]).EFLAGS
+
+;; 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;
+;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
+;; when executing fxsave/fxrstor instruction
+ clts
+ 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]
+
+;; call into exception handler
+ mov ebx, ecx
+ mov eax, 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
+ db 0fh, 0aeh, 0eh ; 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 (IA32_TSS ptr [ecx])._CR3, eax
+ pop eax
+ mov cr4, eax
+
+;; UINT32 EFlags;
+ pop (IA32_TSS ptr [ecx]).EFLAGS
+
+;; UINT32 Ldtr, Tr;
+;; UINT32 Gdtr[2], Idtr[2];
+;; Best not let anyone mess with these particular registers...
+ add esp, 24
+
+;; UINT32 Eip;
+ pop (IA32_TSS ptr [ecx]).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
+ mov (IA32_TSS ptr [ecx])._GS, ax
+ pop eax
+ mov (IA32_TSS ptr [ecx])._FS, ax
+ pop eax
+ mov (IA32_TSS ptr [ecx])._ES, ax
+ pop eax
+ mov (IA32_TSS ptr [ecx])._DS, ax
+ pop eax
+ mov (IA32_TSS ptr [ecx])._CS, ax
+ pop eax
+ mov (IA32_TSS ptr [ecx])._SS, ax
+
+;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pop (IA32_TSS ptr [ecx])._EDI
+ pop (IA32_TSS ptr [ecx])._ESI
+ add esp, 4 ; not for ebp
+ add esp, 4 ; not for esp
+ pop (IA32_TSS ptr [ecx])._EBX
+ pop (IA32_TSS ptr [ecx])._EDX
+ pop (IA32_TSS ptr [ecx])._ECX
+ pop (IA32_TSS ptr [ecx])._EAX
+
+ mov esp, ebp
+
+; Set single step DB# if SMM profile is enabled and page fault exception happens
+ cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0
+ jz @Done2
+
+; Create return context for iretd in stub function
+ mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
+ mov ebx, (IA32_TSS ptr [ecx]).EIP
+ mov [eax - 0ch], ebx ; create EIP in old stack
+ movzx ebx, (IA32_TSS ptr [ecx])._CS
+ mov [eax - 08h], ebx ; create CS in old stack
+ mov ebx, (IA32_TSS ptr [ecx]).EFLAGS
+ bts ebx, 8
+ mov [eax - 04h], ebx ; create eflags in old stack
+ mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
+ sub eax, 0ch ; minus 12 byte
+ mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer
+; Replace the EIP of interrupted task with stub function
+ mov eax, PageFaultStubFunction
+ mov (IA32_TSS ptr [ecx]).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
+PageFaultIdtHandlerSmmProfile ENDP
+
+PageFaultStubFunction PROC
+;
+; we need clean TS bit in CR0 to execute
+; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
+;
+ clts
+ iretd
+PageFaultStubFunction ENDP
+
+InitializeIDTSmmStackGuard PROC USES ebx
+;
+; 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.
+;
+ lea ebx, _SmiIDT + 14 * 8
+ lea edx, TaskGateDescriptor
+ mov eax, [edx]
+ mov [ebx], eax
+ mov eax, [edx + 4]
+ mov [ebx + 4], eax
+ ret
+InitializeIDTSmmStackGuard ENDP
+
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
new file mode 100644
index 0000000000..545b534f27
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
@@ -0,0 +1,96 @@
+/** @file
+ SMM CPU misc functions for Ia32 arch specific.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+/**
+ 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;
+
+ 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 * 2 + 7) & ~7; // 8 bytes aligned
+ GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
+ ASSERT (GdtTssTables != NULL);
+ GdtTableStepSize = GdtTssTableSize;
+
+ for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
+ CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE * 2);
+ //
+ // 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;
+ }
+ } else {
+ //
+ // Just use original table, AllocatePage and copy them here to make sure GDTs are covered in page memory.
+ //
+ GdtTssTableSize = gcSmiGdtr.Limit + 1;
+ GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
+ ASSERT (GdtTssTables != NULL);
+ 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;
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S
new file mode 100644
index 0000000000..e8db33a45a
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S
@@ -0,0 +1,84 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmmInit.S
+#
+# Abstract:
+#
+# Functions for relocating SMBASE's for all processors
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(gSmmCr0)
+ASM_GLOBAL ASM_PFX(gSmmCr3)
+ASM_GLOBAL ASM_PFX(gSmmCr4)
+ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)
+ASM_GLOBAL ASM_PFX(gcSmmInitSize)
+ASM_GLOBAL ASM_PFX(gSmmJmpAddr)
+ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)
+ASM_GLOBAL ASM_PFX(gSmmInitStack)
+ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)
+
+.equ PROTECT_MODE_CS, 0x08
+.equ PROTECT_MODE_DS, 0x20
+
+ .text
+
+ASM_PFX(gcSmiInitGdtr):
+ .word 0
+ .quad 0
+
+SmmStartup:
+ .byte 0x66,0xb8
+ASM_PFX(gSmmCr3): .space 4
+ movl %eax, %cr3
+ .byte 0x67,0x66
+ lgdt %cs:(ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)
+ .byte 0x66,0xb8
+ASM_PFX(gSmmCr4): .space 4
+ movl %eax, %cr4
+ .byte 0x66,0xb8
+ASM_PFX(gSmmCr0): .space 4
+ .byte 0xbf, PROTECT_MODE_DS, 0 # mov di, PROTECT_MODE_DS
+ movl %eax, %cr0
+ .byte 0x66,0xea # jmp far [ptr48]
+ASM_PFX(gSmmJmpAddr): .long Start32bit
+ .word PROTECT_MODE_CS
+Start32bit:
+ movl %edi,%ds
+ movl %edi,%es
+ movl %edi,%fs
+ movl %edi,%gs
+ movl %edi,%ss
+ .byte 0xbc # mov esp, imm32
+ASM_PFX(gSmmInitStack): .space 4
+ call ASM_PFX(SmmInitHandler)
+ rsm
+
+ASM_PFX(gcSmmInitTemplate):
+
+_SmmInitTemplate:
+ .byte 0x66
+ movl $SmmStartup, %ebp
+ .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000
+ jmp *%bp # jmp ebp actually
+
+ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)
+
+
+ASM_PFX(SmmRelocationSemaphoreComplete):
+ pushl %eax
+ movl ASM_PFX(mRebasedFlag), %eax
+ movb $1, (%eax)
+ popl %eax
+ jmp *ASM_PFX(mSmmRelocationOriginalAddress)
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm
new file mode 100644
index 0000000000..9ba2aebe69
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm
@@ -0,0 +1,94 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmmInit.Asm
+;
+; Abstract:
+;
+; Functions for relocating SMBASE's for all processors
+;
+;-------------------------------------------------------------------------------
+
+ .686p
+ .xmm
+ .model flat,C
+
+SmmInitHandler PROTO C
+
+EXTERNDEF C gSmmCr0:DWORD
+EXTERNDEF C gSmmCr3:DWORD
+EXTERNDEF C gSmmCr4:DWORD
+EXTERNDEF C gcSmmInitTemplate:BYTE
+EXTERNDEF C gcSmmInitSize:WORD
+EXTERNDEF C gSmmJmpAddr:QWORD
+EXTERNDEF C mRebasedFlag:PTR BYTE
+EXTERNDEF C mSmmRelocationOriginalAddress:DWORD
+EXTERNDEF C gSmmInitStack:DWORD
+EXTERNDEF C gcSmiInitGdtr:FWORD
+
+PROTECT_MODE_CS EQU 08h
+PROTECT_MODE_DS EQU 20h
+
+ .code
+
+gcSmiInitGdtr LABEL FWORD
+ DW 0
+ DQ 0
+
+SmmStartup PROC
+ DB 66h, 0b8h
+gSmmCr3 DD ?
+ mov cr3, eax
+ DB 67h, 66h
+ lgdt fword ptr cs:[ebp + (offset gcSmiInitGdtr - SmmStartup)]
+ DB 66h, 0b8h
+gSmmCr4 DD ?
+ mov cr4, eax
+ DB 66h, 0b8h
+gSmmCr0 DD ?
+ DB 0bfh, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS
+ mov cr0, eax
+ DB 66h, 0eah ; jmp far [ptr48]
+gSmmJmpAddr LABEL QWORD
+ DD @32bit
+ DW PROTECT_MODE_CS
+@32bit:
+ mov ds, edi
+ mov es, edi
+ mov fs, edi
+ mov gs, edi
+ mov ss, edi
+ DB 0bch ; mov esp, imm32
+gSmmInitStack DD ?
+ call SmmInitHandler
+ rsm
+SmmStartup ENDP
+
+gcSmmInitTemplate LABEL BYTE
+
+_SmmInitTemplate PROC
+ DB 66h
+ mov ebp, SmmStartup
+ DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h
+ jmp bp ; jmp ebp actually
+_SmmInitTemplate ENDP
+
+gcSmmInitSize DW $ - gcSmmInitTemplate
+
+SmmRelocationSemaphoreComplete PROC
+ push eax
+ mov eax, mRebasedFlag
+ mov byte ptr [eax], 1
+ pop eax
+ jmp [mSmmRelocationOriginalAddress]
+SmmRelocationSemaphoreComplete ENDP
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
new file mode 100644
index 0000000000..767cb6908b
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
@@ -0,0 +1,80 @@
+/** @file
+IA-32 processor specific functions to enable SMM profile.
+
+Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+#include "SmmProfileInternal.h"
+
+/**
+ Create SMM page table for S3 path.
+
+**/
+VOID
+InitSmmS3Cr3 (
+ VOID
+ )
+{
+ mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0, 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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
new file mode 100644
index 0000000000..3e15bffc60
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
@@ -0,0 +1,97 @@
+/** @file
+IA-32 processor specific header file to enable SMM profile.
+
+Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
new file mode 100644
index 0000000000..f14b471bcf
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -0,0 +1,1410 @@
+/** @file
+SMM MP service implementation
+
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+//
+// Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE)
+//
+UINT64 gSmiMtrrs[MTRR_NUMBER_OF_FIXED_MTRR + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
+UINT64 gPhyMask;
+SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData = NULL;
+UINTN mSmmMpSyncDataSize;
+SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
+UINTN mSemaphoreSize;
+SPIN_LOCK *mPFLock = NULL;
+
+/**
+ 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;
+ UINTN BspIndex;
+
+ BspIndex = mSmmMpSyncData->BspIndex;
+ for (Index = mMaxNumberOfCpus; Index-- > 0;) {
+ if (Index != BspIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {
+ 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 = mMaxNumberOfCpus; Index-- > 0;) {
+ 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;
+}
+
+
+/**
+ 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;
+
+ ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
+
+ //
+ // 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) &&
+ !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 = mMaxNumberOfCpus; Index-- > 0;) {
+ 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
+ )
+{
+ PROCESSOR_SMM_DESCRIPTOR *Psd;
+ UINT64 *SmiMtrrs;
+ MTRR_SETTINGS *BiosMtrr;
+
+ Psd = (PROCESSOR_SMM_DESCRIPTOR*)(mCpuHotPlugData.SmBase[CpuIndex] + SMM_PSD_OFFSET);
+ SmiMtrrs = (UINT64*)(UINTN)Psd->MtrrBaseMaskPtr;
+
+ SmmCpuFeaturesDisableSmrr ();
+
+ //
+ // Replace all MTRRs registers
+ //
+ BiosMtrr = (MTRR_SETTINGS*)SmiMtrrs;
+ MtrrSetAllMtrrs(BiosMtrr);
+}
+
+/**
+ 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
+ //
+ AcquireSpinLockOrFail (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
+ //
+ for (Index = mMaxNumberOfCpus; Index-- > 0;) {
+ if (Index != CpuIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {
+ AcquireSpinLock (mSmmMpSyncData->CpuData[Index].Busy);
+ ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Busy);
+ }
+ }
+
+ //
+ // 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 = mMaxNumberOfCpus; Index-- > 0;) {
+ 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 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;
+
+ //
+ // 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
+ //
+ (*mSmmMpSyncData->CpuData[CpuIndex].Procedure) (
+ (VOID*)mSmmMpSyncData->CpuData[CpuIndex].Parameter
+ );
+
+ //
+ // 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 ExtraPages Additional page numbers besides for 4G memory
+ @param Is32BitPageTable Whether the page table is 32-bit PAE
+ @return PageTable Address
+
+**/
+UINT32
+Gen4GPageTable (
+ IN UINTN ExtraPages,
+ 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 (ExtraPages + 5 + PagesNeeded);
+ ASSERT (PageTable != NULL);
+
+ PageTable = (VOID *)((UINTN)PageTable + EFI_PAGES_TO_SIZE (ExtraPages));
+ 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) + (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) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
+ }
+
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ Pages = (UINTN)PageTable + EFI_PAGES_TO_SIZE (5);
+ GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE;
+ Pdpte = (UINT64*)PageTable;
+ for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {
+ Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));
+ Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | 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;
+ GuardPage += mSmmStackSize;
+ if (GuardPage > mSmmStackArrayEnd) {
+ GuardPage = 0;
+ }
+ } else {
+ Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;
+ }
+ PageAddress+= EFI_PAGE_SIZE;
+ }
+ Pages += EFI_PAGE_SIZE;
+ }
+ }
+
+ return (UINT32)(UINTN)PageTable;
+}
+
+/**
+ Set memory cache ability.
+
+ @param PageTable PageTable Address
+ @param Address Memory Address to change cache ability
+ @param Cacheability Cache ability to set
+
+**/
+VOID
+SetCacheability (
+ IN UINT64 *PageTable,
+ IN UINTN Address,
+ IN UINT8 Cacheability
+ )
+{
+ UINTN PTIndex;
+ VOID *NewPageTableAddress;
+ UINT64 *NewPageTable;
+ UINTN Index;
+
+ ASSERT ((Address & EFI_PAGE_MASK) == 0);
+
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;
+ ASSERT (PageTable[PTIndex] & IA32_PG_P);
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
+ }
+
+ PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;
+ ASSERT (PageTable[PTIndex] & IA32_PG_P);
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
+
+ //
+ // A perfect implementation should check the original cacheability with the
+ // one being set, and break a 2M page entry into pieces only when they
+ // disagreed.
+ //
+ PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;
+ if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
+ //
+ // Allocate a page from SMRAM
+ //
+ NewPageTableAddress = AllocatePageTableMemory (1);
+ ASSERT (NewPageTableAddress != NULL);
+
+ NewPageTable = (UINT64 *)NewPageTableAddress;
+
+ for (Index = 0; Index < 0x200; Index++) {
+ NewPageTable[Index] = PageTable[PTIndex];
+ if ((NewPageTable[Index] & IA32_PG_PAT_2M) != 0) {
+ NewPageTable[Index] &= ~((UINT64)IA32_PG_PAT_2M);
+ NewPageTable[Index] |= (UINT64)IA32_PG_PAT_4K;
+ }
+ NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);
+ }
+
+ PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;
+ }
+
+ ASSERT (PageTable[PTIndex] & IA32_PG_P);
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
+
+ PTIndex = (UINTN)RShiftU64 (Address, 12) & 0x1ff;
+ ASSERT (PageTable[PTIndex] & IA32_PG_P);
+ PageTable[PTIndex] &= ~((UINT64)((IA32_PG_PAT_4K | IA32_PG_CD | IA32_PG_WT)));
+ PageTable[PTIndex] |= (UINT64)Cacheability;
+}
+
+
+/**
+ 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
+ )
+{
+ if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus ||
+ CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu ||
+ !(*(mSmmMpSyncData->CpuData[CpuIndex].Present)) ||
+ gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove ||
+ !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;
+ mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;
+ ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
+
+ if (FeaturePcdGet (PcdCpuSmmBlockStartupThisAp)) {
+ AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
+ ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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)) {
+ 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)) {
+ 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;
+ BOOLEAN XdDisableFlag;
+
+ //
+ // Save Cr2 because Page Fault exception in SMM may override its value
+ //
+ Cr2 = AsmReadCr2 ();
+
+ //
+ // 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);
+ }
+
+ //
+ // Try to enable XD
+ //
+ XdDisableFlag = FALSE;
+ if (mXdSupported) {
+ if ((AsmReadMsr64 (MSR_IA32_MISC_ENABLE) & B_XD_DISABLE_BIT) != 0) {
+ XdDisableFlag = TRUE;
+ AsmMsrAnd64 (MSR_IA32_MISC_ENABLE, ~B_XD_DISABLE_BIT);
+ }
+ ActivateXd ();
+ }
+
+ 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 ();
+ }
+
+ //
+ // Restore XD
+ //
+ if (XdDisableFlag) {
+ AsmMsrOr64 (MSR_IA32_MISC_ENABLE, B_XD_DISABLE_BIT);
+ }
+ }
+
+Exit:
+ SmmCpuFeaturesRendezvousExit (CpuIndex);
+ //
+ // Restore Cr2
+ //
+ AsmWriteCr2 (Cr2);
+}
+
+/**
+ Allocate buffer for all semaphores and spin locks.
+
+**/
+VOID
+InitializeSmmCpuSemaphores (
+ VOID
+ )
+{
+ UINTN ProcessorCount;
+ UINTN TotalSize;
+ UINTN GlobalSemaphoresSize;
+ UINTN CpuSemaphoresSize;
+ UINTN MsrSemahporeSize;
+ 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;
+ MsrSemahporeSize = MSR_SPIN_LOCK_INIT_NUM * SemaphoreSize;
+ TotalSize = GlobalSemaphoresSize + CpuSemaphoresSize + MsrSemahporeSize;
+ 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 = (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;
+
+ SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize + CpuSemaphoresSize;
+ mSmmCpuSemaphores.SemaphoreMsr.Msr = (SPIN_LOCK *)SemaphoreAddr;
+ mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter =
+ ((UINTN)SemaphoreBlock + Pages * SIZE_4KB - SemaphoreAddr) / SemaphoreSize;
+ ASSERT (mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter >= MSR_SPIN_LOCK_INIT_NUM);
+
+ 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 = (SMM_CPU_SYNC_MODE) PcdGet8 (PcdCpuSmmSyncMode);
+
+ 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);
+ }
+ }
+}
+
+/**
+ 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.
+
+**/
+UINT32
+InitializeMpServiceData (
+ IN VOID *Stacks,
+ IN UINTN StackSize
+ )
+{
+ UINT32 Cr3;
+ UINTN Index;
+ MTRR_SETTINGS *Mtrr;
+ PROCESSOR_SMM_DESCRIPTOR *Psd;
+ UINT8 *GdtTssTables;
+ UINTN GdtTableStepSize;
+
+ //
+ // 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);
+ 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);
+
+ //
+ // Initialize PROCESSOR_SMM_DESCRIPTOR for each CPU
+ //
+ for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
+ Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)(UINTN)(mCpuHotPlugData.SmBase[Index] + SMM_PSD_OFFSET);
+ CopyMem (Psd, &gcPsd, sizeof (gcPsd));
+ Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);
+ Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;
+
+ //
+ // Install SMI handler
+ //
+ InstallSmiHandler (
+ Index,
+ (UINT32)mCpuHotPlugData.SmBase[Index],
+ (VOID*)((UINTN)Stacks + (StackSize * Index)),
+ StackSize,
+ (UINTN)Psd->SmmGdtPtr,
+ Psd->SmmGdtSize,
+ gcSmiIdtr.Base,
+ gcSmiIdtr.Limit + 1,
+ Cr3
+ );
+ }
+
+ //
+ // Record current MTRR settings
+ //
+ ZeroMem(gSmiMtrrs, sizeof (gSmiMtrrs));
+ Mtrr = (MTRR_SETTINGS*)gSmiMtrrs;
+ MtrrGetAllMtrrs (Mtrr);
+
+ 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;
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
new file mode 100644
index 0000000000..8b3bb343ce
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -0,0 +1,1517 @@
+/** @file
+Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
+
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "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
+ },
+};
+
+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
+};
+
+EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
+
+//
+// SMM stack information
+//
+UINTN mSmmStackArrayBase;
+UINTN mSmmStackArrayEnd;
+UINTN mSmmStackSize;
+
+//
+// Pointer to structure used during S3 Resume
+//
+SMM_S3_RESUME_STATE *mSmmS3ResumeState = NULL;
+
+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;
+
+//
+// Spin lock used to serialize setting of SMM Code Access Check feature
+//
+SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
+
+/**
+ Initialize IDT to setup exception handlers for SMM.
+
+**/
+VOID
+InitializeSmmIdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+ IA32_DESCRIPTOR DxeIdtr;
+ //
+ // 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;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ VOID *PdbPointer;
+ UINT64 DumpIpAddress;
+
+ //
+ // Find Image Base
+ //
+ Pe32Data = CallerIpAddress & ~(SIZE_4KB - 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 < CallerIpAddress)) {
+ if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
+ //
+ // It's PE image.
+ //
+ break;
+ }
+ }
+ }
+
+ //
+ // Not found the image base, check the previous aligned address
+ //
+ Pe32Data -= SIZE_4KB;
+ }
+
+ DumpIpAddress = CallerIpAddress;
+ DEBUG ((EFI_D_ERROR, "It is invoked from the instruction before IP(0x%lx)", DumpIpAddress));
+
+ if (Pe32Data != 0) {
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
+ if (PdbPointer != NULL) {
+ DEBUG ((EFI_D_ERROR, " in module (%a)", 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_PARAMTER 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;
+ }
+
+ //
+ // 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_PARAMTER 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 <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+
+ 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 (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
+ //
+ gSmmCr0 = (UINT32)AsmReadCr0 ();
+ gSmmCr3 = (UINT32)AsmReadCr3 ();
+ gSmmCr4 = (UINT32)AsmReadCr4 ();
+
+ //
+ // 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));
+}
+
+/**
+ 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"));
+
+ //
+ // 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
+ //
+ EarlyInitializeCpu ();
+ }
+
+ //
+ // 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
+ //
+ InitializeCpu ();
+ }
+
+ //
+ // 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 ();
+}
+
+/**
+ 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;
+ UINTN Index1;
+ CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
+
+ CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
+ for (Index = 0; Index < NumberOfCpus; Index++) {
+ DestinationRegisterTableList[Index].RegisterTableEntry = AllocatePool (DestinationRegisterTableList[Index].AllocatedSize);
+ ASSERT (DestinationRegisterTableList[Index].RegisterTableEntry != NULL);
+ CopyMem (DestinationRegisterTableList[Index].RegisterTableEntry, SourceRegisterTableList[Index].RegisterTableEntry, DestinationRegisterTableList[Index].AllocatedSize);
+ //
+ // Go though all MSRs in register table to initialize MSR spin lock
+ //
+ RegisterTableEntry = DestinationRegisterTableList[Index].RegisterTableEntry;
+ for (Index1 = 0; Index1 < DestinationRegisterTableList[Index].TableLength; Index1++, RegisterTableEntry++) {
+ if ((RegisterTableEntry->RegisterType == Msr) && (RegisterTableEntry->ValidBitLength < 64)) {
+ //
+ // Initialize MSR spin lock only for those MSRs need bit field writing
+ //
+ InitMsrSpinLockByIndex (RegisterTableEntry->Index);
+ }
+ }
+ }
+}
+
+/**
+ 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
+ )
+{
+ ACPI_CPU_DATA *AcpiCpuData;
+ IA32_DESCRIPTOR *Gdtr;
+ IA32_DESCRIPTOR *Idtr;
+
+ //
+ // 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) {
+ goto Done;
+ }
+
+ //
+ // 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;
+
+ mGdtForAp = AllocatePool ((Gdtr->Limit + 1) + (Idtr->Limit + 1) + mAcpiCpuData.ApMachineCheckHandlerSize);
+ ASSERT (mGdtForAp != NULL);
+ mIdtForAp = (VOID *) ((UINTN)mGdtForAp + (Gdtr->Limit + 1));
+ mMachineCheckHandlerForAp = (VOID *) ((UINTN)mIdtForAp + (Idtr->Limit + 1));
+
+ CopyMem (mGdtForAp, (VOID *)Gdtr->Base, Gdtr->Limit + 1);
+ CopyMem (mIdtForAp, (VOID *)Idtr->Base, Idtr->Limit + 1);
+ CopyMem (mMachineCheckHandlerForAp, (VOID *)(UINTN)mAcpiCpuData.ApMachineCheckHandlerBase, mAcpiCpuData.ApMachineCheckHandlerSize);
+
+Done:
+ //
+ // 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;
+ VOID *GuidHob;
+ EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
+ SMM_S3_RESUME_STATE *SmmS3ResumeState;
+ UINT8 *Stacks;
+ VOID *Registration;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+ UINT32 Cr3;
+
+ //
+ // 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
+ );
+
+ //
+ // Fix segment address of the long-mode-switch jump
+ //
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;
+ }
+
+ //
+ // 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));
+
+ //
+ // 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;
+ }
+ }
+
+ //
+ // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU
+ // specific context in a PROCESSOR_SMM_DESCRIPTOR, and the SMI entry point. This size
+ // is rounded up to nearest power of 2.
+ //
+ TileCodeSize = GetSmiHandlerSize ();
+ TileCodeSize = ALIGN_VALUE(TileCodeSize, SIZE_4KB);
+ TileDataSize = sizeof (SMRAM_SAVE_STATE_MAP) + sizeof (PROCESSOR_SMM_DESCRIPTOR);
+ 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 PROCESSOR_SMM_DESCRIPTOR of CPU[i+1] and the SMRAM Save State Map of CPU[i+1],
+ // the ASSERT(). If this ASSERT() is triggered, then the SMI Handler size 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 = AllocateAlignedPages (BufferPages, SIZE_32KB);
+ } else {
+ Buffer = AllocateAlignedPages (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.
+ //
+ 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 (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2);
+ Stacks = (UINT8 *) AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2));
+ ASSERT (Stacks != NULL);
+ mSmmStackArrayBase = (UINTN)Stacks;
+ mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize - 1;
+ } else {
+ mSmmStackSize = PcdGet32 (PcdCpuSmmStackSize);
+ Stacks = (UINT8 *) AllocatePages (EFI_SIZE_TO_PAGES (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize));
+ ASSERT (Stacks != NULL);
+ }
+
+ //
+ // Set SMI stack for SMM base relocation
+ //
+ gSmmInitStack = (UINTN) (Stacks + mSmmStackSize - 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 ();
+
+ //
+ // SMM Time initialization
+ //
+ InitializeSmmTimer ();
+
+ //
+ // Initialize MP globals
+ //
+ Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize);
+
+ //
+ // 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);
+
+ //
+ // 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);
+
+ GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
+ if (GuidHob != NULL) {
+ 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 = gSmmCr0;
+ SmmS3ResumeState->SmmS3Cr3 = Cr3;
+ SmmS3ResumeState->SmmS3Cr4 = gSmmCr4;
+
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_64;
+ }
+ if (sizeof (UINTN) == sizeof (UINT32)) {
+ SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_32;
+ }
+ }
+
+ //
+ // Check XD and BTS features
+ //
+ CheckProcessorFeature ();
+
+ //
+ // Initialize SMM Profile feature
+ //
+ InitSmmProfile (Cr3);
+
+ //
+ // Patch SmmS3ResumeState->SmmS3Cr3
+ //
+ InitSmmS3Cr3 ();
+
+ 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;
+ EFI_SMRAM_DESCRIPTOR *SmramRanges;
+ UINTN SmramRangeCount;
+ 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);
+
+ SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
+ ASSERT (SmramRanges != NULL);
+
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ SmramRangeCount = 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 < SmramRangeCount; Index++) {
+ //
+ // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
+ //
+ if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ continue;
+ }
+
+ if (SmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
+ if (SmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = SmramRanges[Index].PhysicalSize;
+ CurrentSmramRange = &SmramRanges[Index];
+ }
+ }
+ }
+ }
+
+ ASSERT (CurrentSmramRange != NULL);
+
+ *SmrrBase = (UINT32)CurrentSmramRange->CpuStart;
+ *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize;
+
+ do {
+ Found = FALSE;
+ for (Index = 0; Index < SmramRangeCount; Index++) {
+ if (SmramRanges[Index].CpuStart < *SmrrBase && *SmrrBase == (SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize)) {
+ *SmrrBase = (UINT32)SmramRanges[Index].CpuStart;
+ *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
+ Found = TRUE;
+ } else if ((*SmrrBase + *SmrrSize) == SmramRanges[Index].CpuStart && SmramRanges[Index].PhysicalSize > 0) {
+ *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[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) {
+
+ //
+ // 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);
+}
+
+/**
+ 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 ();
+ //
+ // 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
+ )
+{
+ //
+ // 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;
+ }
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
new file mode 100644
index 0000000000..dfdafa61fa
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -0,0 +1,797 @@
+/** @file
+Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
+
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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_PISMMCPUDXESMM_H_
+#define _CPU_PISMMCPUDXESMM_H_
+
+#include <PiSmm.h>
+
+#include <Protocol/MpService.h>
+#include <Protocol/SmmConfiguration.h>
+#include <Protocol/SmmCpu.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmCpuService.h>
+
+#include <Guid/AcpiS3Context.h>
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/SmmCpuPlatformHookLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/HobLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SmmCpuFeaturesLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+
+#include <AcpiCpuData.h>
+#include <CpuHotPlugData.h>
+
+#include <Register/Cpuid.h>
+
+#include "CpuService.h"
+#include "SmmProfile.h"
+
+//
+// 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_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)
+
+//
+// Size of Task-State Segment defined in IA32 Manual
+//
+#define TSS_SIZE 104
+#define TSS_X64_IST1_OFFSET 36
+#define TSS_IA32_CR3_OFFSET 28
+#define TSS_IA32_ESP_OFFSET 56
+
+//
+// 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
+
+//
+// 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;
+} SMM_CPU_PRIVATE_DATA;
+
+extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
+extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
+extern UINTN mMaxNumberOfCpus;
+extern UINTN mNumberOfCpus;
+extern BOOLEAN mRestoreSmmConfigurationInS3;
+extern EFI_SMM_CPU_PROTOCOL mSmmCpu;
+
+///
+/// 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_PARAMTER 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_PARAMTER 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_PARAMTER 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_PARAMTER 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
+ );
+
+//
+//
+//
+typedef struct {
+ UINT32 Offset;
+ UINT16 Segment;
+ UINT16 Reserved;
+} IA32_FAR_ADDRESS;
+
+extern IA32_FAR_ADDRESS gSmmJmpAddr;
+
+extern CONST UINT8 gcSmmInitTemplate[];
+extern CONST UINT16 gcSmmInitSize;
+extern UINT32 gSmmCr0;
+extern UINT32 gSmmCr3;
+extern UINT32 gSmmCr4;
+extern UINTN gSmmInitStack;
+
+/**
+ 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_PROCEDURE Procedure;
+ volatile VOID *Parameter;
+ volatile UINT32 *Run;
+ volatile BOOLEAN *Present;
+} 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;
+} SMM_DISPATCHER_MP_SYNC_DATA;
+
+#define MSR_SPIN_LOCK_INIT_NUM 15
+
+typedef struct {
+ SPIN_LOCK *SpinLock;
+ UINT32 MsrIndex;
+} MP_MSR_LOCK;
+
+#define SMM_PSD_OFFSET 0xfb00
+
+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 MtrrBaseMaskPtr; // Offset 0x58
+} PROCESSOR_SMM_DESCRIPTOR;
+
+
+///
+/// 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;
+} SMM_CPU_SEMAPHORE_CPU;
+
+///
+/// All MSRs semaphores' pointer and counter
+///
+typedef struct {
+ SPIN_LOCK *Msr;
+ UINTN AvailableCounter;
+} SMM_CPU_SEMAPHORE_MSR;
+
+///
+/// All semaphores' information
+///
+typedef struct {
+ SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
+ SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
+ SMM_CPU_SEMAPHORE_MSR SemaphoreMsr;
+} SMM_CPU_SEMAPHORES;
+
+extern IA32_DESCRIPTOR gcSmiGdtr;
+extern IA32_DESCRIPTOR gcSmiIdtr;
+extern VOID *gcSmiIdtrPtr;
+extern CONST PROCESSOR_SMM_DESCRIPTOR gcPsd;
+extern UINT64 gPhyMask;
+extern ACPI_CPU_DATA mAcpiCpuData;
+extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData;
+extern VOID *mGdtForAp;
+extern VOID *mIdtForAp;
+extern VOID *mMachineCheckHandlerForAp;
+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;
+
+/**
+ Create 4G PageTable in SMRAM.
+
+ @param ExtraPages Additional page numbers besides for 4G memory
+ @param Is32BitPageTable Whether the page table is 32-bit PAE
+ @return PageTable Address
+
+**/
+UINT32
+Gen4GPageTable (
+ IN UINTN ExtraPages,
+ 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.
+
+**/
+UINT32
+InitializeMpServiceData (
+ IN VOID *Stacks,
+ IN UINTN StackSize
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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
+EarlyInitializeCpu (
+ VOID
+ );
+
+/**
+ 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
+InitializeCpu (
+ 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 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
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
new file mode 100644
index 0000000000..122318f02e
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -0,0 +1,161 @@
+## @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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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
+
+[Sources.Ia32]
+ Ia32/Semaphore.c
+ Ia32/PageTbl.c
+ Ia32/SmmFuncsArch.c
+ Ia32/SmmProfileArch.c
+ Ia32/SmmProfileArch.h
+ Ia32/SmmInit.asm | MSFT
+ Ia32/SmiEntry.asm | MSFT
+ Ia32/SmiException.asm | MSFT
+ Ia32/MpFuncs.asm | MSFT
+
+ Ia32/SmmInit.asm | INTEL
+ Ia32/SmiEntry.asm | INTEL
+ Ia32/SmiException.asm | INTEL
+ Ia32/MpFuncs.asm | INTEL
+
+ Ia32/SmmInit.S | GCC
+ Ia32/SmiEntry.S | GCC
+ Ia32/SmiException.S | GCC
+ Ia32/MpFuncs.S | GCC
+
+[Sources.X64]
+ X64/Semaphore.c
+ X64/PageTbl.c
+ X64/SmmFuncsArch.c
+ X64/SmmProfileArch.c
+ X64/SmmProfileArch.h
+ X64/SmmInit.asm | MSFT
+ X64/SmiEntry.asm | MSFT
+ X64/SmiException.asm | MSFT
+ X64/MpFuncs.asm | MSFT
+
+ X64/SmmInit.asm | INTEL
+ X64/SmiEntry.asm | INTEL
+ X64/SmiException.asm | INTEL
+ X64/MpFuncs.asm | INTEL
+
+ X64/SmmInit.S | GCC
+ X64/SmiEntry.S | GCC
+ X64/SmiException.S | GCC
+ X64/MpFuncs.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+ CacheMaintenanceLib
+ 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
+
+[Guids]
+ gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.
+ gEfiGlobalVariableGuid ## SOMETIMES_PRODUCES ## Variable:L"SmmProfileData"
+ gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiAcpi10TableGuid ## SOMETIMES_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
+
+[Depex]
+ gEfiMpServiceProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ PiSmmCpuDxeSmmExtra.uni
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni
new file mode 100644
index 0000000000..98eae1d697
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni
@@ -0,0 +1,21 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials are
+// licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni
new file mode 100644
index 0000000000..d0a8d54006
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// PiSmmCpuDxeSmm Localized Strings and Content
+//
+// Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are
+// licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Processor SMM Initialization DXE Driver"
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
new file mode 100644
index 0000000000..71fff0e5b0
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -0,0 +1,1434 @@
+/** @file
+Enable SMM profile.
+
+Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "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 = FALSE;
+
+//
+// The flag indicates if execute-disable is enabled on processor.
+//
+BOOLEAN mXdEnabled = FALSE;
+
+//
+// The flag indicates if BTS is supported by processor.
+//
+BOOLEAN mBtsSupported = FALSE;
+
+//
+// The flag indicates if SMM profile starts to record data.
+//
+BOOLEAN mSmmProfileStart = 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},
+
+ //
+ // 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 < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); 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) {
+ 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 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;
+
+ *Nx = FALSE;
+ 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 {
+ if ((Address < mCpuHotPlugData.SmrrBase) ||
+ (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
+ *Nx = TRUE;
+ }
+ 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 NumberOfMmioDescriptors;
+ 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;
+ NumberOfMmioDescriptors = 0;
+ 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) {
+ NumberOfMmioDescriptors++;
+ }
+ }
+
+ if (NumberOfMmioDescriptors != 0) {
+ TotalSize = NumberOfMmioDescriptors * 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 MMIO ranges which are set to present and execution-disable.
+ //
+ NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
+ 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++;
+ }
+ }
+
+ //
+ // 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 *Pml4;
+ UINT64 *Pde;
+ UINT64 *Pte;
+ UINT64 *Pt;
+ UINTN Address;
+ UINTN Level1;
+ UINTN Level2;
+ UINTN Level3;
+ UINTN Level4;
+ UINTN NumberOfPdpEntries;
+ UINTN NumberOfPml4Entries;
+ UINTN SizeOfMemorySpace;
+ BOOLEAN Nx;
+
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ Pml4 = (UINT64*)(UINTN)mSmmProfileCr3;
+ SizeOfMemorySpace = HighBitSet64 (gPhyMask) + 1;
+ //
+ // Calculate the table entries of PML4E and PDPTE.
+ //
+ if (SizeOfMemorySpace <= 39 ) {
+ NumberOfPml4Entries = 1;
+ NumberOfPdpEntries = (UINT32)LShiftU64 (1, (SizeOfMemorySpace - 30));
+ } else {
+ NumberOfPml4Entries = (UINT32)LShiftU64 (1, (SizeOfMemorySpace - 39));
+ NumberOfPdpEntries = 512;
+ }
+ } else {
+ NumberOfPml4Entries = 1;
+ NumberOfPdpEntries = 4;
+ }
+
+ //
+ // Go through page table and change 2MB-page into 4KB-page.
+ //
+ for (Level1 = 0; Level1 < NumberOfPml4Entries; Level1++) {
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ if ((Pml4[Level1] & IA32_PG_P) == 0) {
+ //
+ // If Pml4 entry does not exist, skip it
+ //
+ continue;
+ }
+ Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK);
+ } else {
+ Pde = (UINT64*)(UINTN)mSmmProfileCr3;
+ }
+ for (Level2 = 0; Level2 < NumberOfPdpEntries; Level2++, Pde++) {
+ if ((*Pde & IA32_PG_P) == 0) {
+ //
+ // If PDE entry does not exist, skip it
+ //
+ continue;
+ }
+ Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK);
+ if (Pte == 0) {
+ continue;
+ }
+ for (Level3 = 0; Level3 < SIZE_4KB / sizeof (*Pte); Level3++, Pte++) {
+ if ((*Pte & IA32_PG_P) == 0) {
+ //
+ // If PTE entry does not exist, skip it
+ //
+ continue;
+ }
+ Address = (((Level2 << 9) + Level3) << 21);
+
+ //
+ // If it is 2M page, check IsAddressSplit()
+ //
+ if (((*Pte & IA32_PG_PS) != 0) && IsAddressSplit (Address)) {
+ //
+ // Based on current page table, create 4KB page table for split area.
+ //
+ ASSERT (Address == (*Pte & PHYSICAL_ADDRESS_MASK));
+
+ Pt = AllocatePageTableMemory (1);
+ ASSERT (Pt != NULL);
+
+ // Split it
+ for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++) {
+ Pt[Level4] = Address + ((Level4 << 12) | PAGE_ATTRIBUTE_BITS);
+ } // end for PT
+ *Pte = (UINTN)Pt | PAGE_ATTRIBUTE_BITS;
+ } // end if IsAddressSplit
+ } // end for PTE
+ } // end for PDE
+ }
+
+ //
+ // 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 (Level1 = 0; Level1 < NumberOfPml4Entries; Level1++) {
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ if ((Pml4[Level1] & IA32_PG_P) == 0) {
+ //
+ // If Pml4 entry does not exist, skip it
+ //
+ continue;
+ }
+ Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK);
+ } else {
+ Pde = (UINT64*)(UINTN)mSmmProfileCr3;
+ }
+ for (Level2 = 0; Level2 < NumberOfPdpEntries; Level2++, Pde++) {
+ if ((*Pde & IA32_PG_P) == 0) {
+ //
+ // If PDE entry does not exist, skip it
+ //
+ continue;
+ }
+ Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK);
+ if (Pte == 0) {
+ continue;
+ }
+ for (Level3 = 0; Level3 < SIZE_4KB / sizeof (*Pte); Level3++, Pte++) {
+ if ((*Pte & IA32_PG_P) == 0) {
+ //
+ // If PTE entry does not exist, skip it
+ //
+ continue;
+ }
+ Address = (((Level2 << 9) + Level3) << 21);
+
+ if ((*Pte & IA32_PG_PS) != 0) {
+ // 2MB page
+
+ if (!IsAddressValid (Address, &Nx)) {
+ //
+ // Patch to remove Present flag and RW flag
+ //
+ *Pte = *Pte & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
+ }
+ if (Nx && mXdSupported) {
+ *Pte = *Pte | IA32_PG_NX;
+ }
+ } else {
+ // 4KB page
+ Pt = (UINT64 *)(UINTN)(*Pte & PHYSICAL_ADDRESS_MASK);
+ if (Pt == 0) {
+ continue;
+ }
+ for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++, 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 PTE
+ } // end for PDE
+ }
+
+ //
+ // Flush TLB
+ //
+ CpuFlushTlb ();
+ DEBUG ((EFI_D_INFO, "Patch page table done!\n"));
+ //
+ // Set execute-disable flag
+ //
+ mXdEnabled = TRUE;
+
+ return ;
+}
+
+/**
+ To find FADT in ACPI tables.
+
+ @param AcpiTableGuid The GUID used to find ACPI table in UEFI ConfigurationTable.
+
+ @return FADT table pointer.
+**/
+EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *
+FindAcpiFadtTableByAcpiGuid (
+ IN EFI_GUID *AcpiTableGuid
+ )
+{
+ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
+ UINTN Index;
+ UINT32 Data32;
+ Rsdp = NULL;
+ Rsdt = NULL;
+ Fadt = NULL;
+ //
+ // found ACPI table RSD_PTR from system table
+ //
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {
+ //
+ // A match was found.
+ //
+ Rsdp = gST->ConfigurationTable[Index].VendorTable;
+ break;
+ }
+ }
+
+ if (Rsdp == NULL) {
+ return NULL;
+ }
+
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
+ if (Rsdt == NULL || Rsdt->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ return NULL;
+ }
+
+ for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Rsdt->Length; Index = Index + sizeof (UINT32)) {
+
+ Data32 = *(UINT32 *) ((UINT8 *) Rsdt + Index);
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) (UINT32 *) (UINTN) Data32;
+ if (Fadt->Header.Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+ break;
+ }
+ }
+
+ if (Fadt == NULL || Fadt->Header.Signature != EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+ return NULL;
+ }
+
+ return Fadt;
+}
+
+/**
+ To find FADT in ACPI tables.
+
+ @return FADT table pointer.
+**/
+EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *
+FindAcpiFadtTable (
+ VOID
+ )
+{
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
+
+ Fadt = FindAcpiFadtTableByAcpiGuid (&gEfiAcpi20TableGuid);
+ if (Fadt != NULL) {
+ return Fadt;
+ }
+
+ return FindAcpiFadtTableByAcpiGuid (&gEfiAcpi10TableGuid);
+}
+
+/**
+ 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 = FindAcpiFadtTable ();
+ 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) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (mPFEntryCount != NULL);
+ mLastPFEntryValue = (UINT64 (*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool (
+ sizeof (mLastPFEntryValue[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (mLastPFEntryValue != NULL);
+ mLastPFEntryPointer = (UINT64 *(*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool (
+ sizeof (mLastPFEntryPointer[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ 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 *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (mMsrDsArea != NULL);
+ mMsrBTSRecord = (BRANCH_TRACE_RECORD **)AllocateZeroPool (sizeof (BRANCH_TRACE_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (mMsrBTSRecord != NULL);
+ mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (mMsrPEBSRecord != NULL);
+
+ mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + mSmmProfileSize);
+ MsrDsAreaSizePerCpu = mMsrDsAreaSize / PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ mBTSRecordNumber = (MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER - sizeof(MSR_DS_AREA_STRUCT)) / sizeof(BRANCH_TRACE_RECORD);
+ for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); 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 XD feature is supported by a processor.
+
+ @param[in,out] Buffer The pointer to private data buffer.
+
+**/
+VOID
+EFIAPI
+CheckFeatureSupported (
+ IN OUT VOID *Buffer
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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.
+ //
+ if ((AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 11, 11) == 0) &&
+ (AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 12, 12) == 0)) {
+ //
+ // BTS facilities is supported.
+ //
+ mBtsSupported = FALSE;
+ }
+ }
+ }
+}
+
+/**
+ Check if XD and BTS features are supported by all processors.
+
+**/
+VOID
+CheckProcessorFeature (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_MP_SERVICES_PROTOCOL *MpServices;
+
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // First detect if XD and BTS are supported
+ //
+ mXdSupported = TRUE;
+ mBtsSupported = TRUE;
+
+ //
+ // Check if XD and BTS are supported on all processors.
+ //
+ CheckFeatureSupported (NULL);
+
+ //
+ //Check on other processors if BSP supports this
+ //
+ if (mXdSupported || mBtsSupported) {
+ MpServices->StartupAllAPs (
+ MpServices,
+ CheckFeatureSupported,
+ TRUE,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ );
+ }
+}
+
+/**
+ Enable XD feature.
+
+**/
+VOID
+ActivateXd (
+ VOID
+ )
+{
+ UINT64 MsrRegisters;
+
+ MsrRegisters = AsmReadMsr64 (MSR_EFER);
+ if ((MsrRegisters & MSR_EFER_XD) != 0) {
+ return ;
+ }
+ MsrRegisters |= MSR_EFER_XD;
+ AsmWriteMsr64 (MSR_EFER, MsrRegisters);
+}
+
+/**
+ 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 ;
+ }
+ AsmWriteMsr64 (MSR_LER_FROM_LIP, 0);
+ AsmWriteMsr64 (MSR_LER_TO_LIP, 0);
+ 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)) {
+ return;
+ }
+
+ //
+ // Initialize SmmProfile here
+ //
+ InitSmmProfileInternal ();
+
+ //
+ // Initialize profile IDT.
+ //
+ InitIdtr ();
+}
+
+/**
+ 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;
+
+ //
+ // 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;
+ }
+ }
+}
+
+/**
+ 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;
+ 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 ();
+
+ if (PFAddress <= 0xFFFFFFFF) {
+ RestorePageTableBelow4G (PageTable, PFAddress, CpuIndex, ErrorCode);
+ } else {
+ RestorePageTableAbove4G (PageTable, PFAddress, CpuIndex, ErrorCode, &IsValidPFAddress);
+ }
+
+ 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
+ )
+{
+ SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_DEBUG, DebugExceptionHandler);
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
new file mode 100644
index 0000000000..5488c148e8
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
@@ -0,0 +1,138 @@
+/** @file
+SMM profile header file.
+
+Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _SMM_PROFILE_H_
+#define _SMM_PROFILE_H_
+
+#include "SmmProfileInternal.h"
+
+///
+/// MSR Register Index
+///
+#define MSR_IA32_MISC_ENABLE 0x1A0
+#define B_XD_DISABLE_BIT BIT34
+
+//
+// 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 XD feature is supported by a processor.
+
+ @param[in,out] Buffer The pointer to private data buffer.
+
+**/
+VOID
+EFIAPI
+CheckFeatureSupported (
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Enable XD feature.
+
+**/
+VOID
+ActivateXd (
+ VOID
+ );
+
+/**
+ Update page table according to protected memory ranges and the 4KB-page mapped memory ranges.
+
+**/
+VOID
+InitPaging (
+ VOID
+ );
+
+/**
+ Check if XD and BTS features are supported by all processors.
+
+**/
+VOID
+CheckProcessorFeature (
+ VOID
+ );
+
+extern BOOLEAN mXdSupported;
+extern BOOLEAN mXdEnabled;
+
+#endif // _SMM_PROFILE_H_
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
new file mode 100644
index 0000000000..de6eb0aceb
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
@@ -0,0 +1,172 @@
+/** @file
+SMM profile internal header file.
+
+Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _SMM_PROFILE_INTERNAL_H_
+#define _SMM_PROFILE_INTERNAL_H_
+
+#include <Guid/GlobalVariable.h>
+#include <Guid/Acpi.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/CpuLib.h>
+#include <IndustryStandard/Acpi.h>
+
+#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_P (1u << 0)
+#define IA32_PF_EC_WR (1u << 1)
+#define IA32_PF_EC_US (1u << 2)
+#define IA32_PF_EC_RSVD (1u << 3)
+#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_LASTBRANCH_TOS 0x1C9
+#define MSR_LER_FROM_LIP 0x1DD
+#define MSR_LER_TO_LIP 0x1DE
+#define MSR_DS_AREA 0x600
+
+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;
+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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
new file mode 100644
index 0000000000..539c0294cd
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
@@ -0,0 +1,700 @@
+/** @file
+Provides services to access SMRAM Save State Map
+
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 <PiSmm.h>
+
+#include <Library/SmmCpuFeaturesLib.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Register/Cpuid.h>
+#include <Register/SmramSaveStateMap.h>
+
+//
+// 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
+///
+extern UINT32 gSmbase;
+extern volatile UINT32 gSmiStack;
+extern UINT32 gSmiCr3;
+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_PARAMTER 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_PARAMTER 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;
+ VOID *IoMemAddr;
+
+ //
+ // 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;
+ }
+
+ //
+ // 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];
+ if (IoInfo->IoType == EFI_SMM_SAVE_STATE_IO_TYPE_INPUT || IoInfo->IoType == EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT) {
+ ReadSaveStateRegister (CpuIndex, EFI_SMM_SAVE_STATE_REGISTER_RAX, mSmmCpuIoWidth[IoMisc.Bits.Length].Width, &IoInfo->IoData);
+ }
+ else {
+ ReadSaveStateRegisterByIndex(CpuIndex, SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX, sizeof(IoMemAddr), &IoMemAddr);
+ CopyMem(&IoInfo->IoData, IoMemAddr, mSmmCpuIoWidth[IoMisc.Bits.Length].Width);
+ }
+ 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_PARAMTER 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
+ )
+{
+ if (SmmCpuFeaturesGetSmiHandlerSize () != 0) {
+ //
+ // Install SMI handler provided by library
+ //
+ SmmCpuFeaturesInstallSmiHandler (
+ CpuIndex,
+ SmBase,
+ SmiStack,
+ StackSize,
+ GdtBase,
+ GdtSize,
+ IdtBase,
+ IdtSize,
+ Cr3
+ );
+ return;
+ }
+
+ //
+ // Initialize values in template before copy
+ //
+ gSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN));
+ gSmiCr3 = Cr3;
+ gSmbase = SmBase;
+ gSmiHandlerIdtr.Base = IdtBase;
+ gSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1);
+
+ //
+ // Set the value at the top of the CPU stack to the CPU Index
+ //
+ *(UINTN*)(UINTN)gSmiStack = CpuIndex;
+
+ //
+ // Copy template to CPU specific SMI handler location
+ //
+ CopyMem (
+ (VOID*)(UINTN)(SmBase + SMM_HANDLER_OFFSET),
+ (VOID*)gcSmiHandlerTemplate,
+ gcSmiHandlerSize
+ );
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
new file mode 100644
index 0000000000..5a632eaa24
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
@@ -0,0 +1,116 @@
+/** @file
+SMM Timer feature support
+
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S
new file mode 100644
index 0000000000..d7cbc8cdc5
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S
@@ -0,0 +1,204 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# MpFuncs.S
+#
+# Abstract:
+#
+# This is the assembly code for Multi-processor S3 support
+#
+#------------------------------------------------------------------------------
+
+.equ VacantFlag, 0x0
+.equ NotVacantFlag, 0xff
+
+.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+.equ StackStartAddressLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08
+.equ StackSizeLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
+.equ CProcedureLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x18
+.equ GdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20
+.equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A
+.equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34
+.equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38
+
+#-------------------------------------------------------------------------------------
+#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);
+
+.code:
+
+ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)
+ASM_PFX(RendezvousFunnelProc):
+RendezvousFunnelProcStart:
+
+# At this point CS = 0x(vv00) and ip= 0x0.
+
+ .byte 0x8c,0xc8 # mov ax, cs
+ .byte 0x8e,0xd8 # mov ds, ax
+ .byte 0x8e,0xc0 # mov es, ax
+ .byte 0x8e,0xd0 # mov ss, ax
+ .byte 0x33,0xc0 # xor ax, ax
+ .byte 0x8e,0xe0 # mov fs, ax
+ .byte 0x8e,0xe8 # mov gs, ax
+
+flat32Start:
+
+ .byte 0xBE
+ .word BufferStartLocation
+ .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
+
+ .byte 0xBE
+ .word Cr3OffsetLocation
+ .byte 0x66,0x8B,0xC # mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
+
+ .byte 0xBE
+ .word GdtrLocation
+ .byte 0x66 # db 66h
+ .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]
+
+ .byte 0xBE
+ .word IdtrLocation
+ .byte 0x66 # db 66h
+ .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]
+
+ .byte 0x33,0xC0 # xor ax, ax
+ .byte 0x8E,0xD8 # mov ds, ax
+
+ .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0
+ .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)
+ .byte 0xF,0x22,0xC0 # mov cr0, eax
+
+FLAT32_JUMP:
+
+ .byte 0x66,0x67,0xEA # far jump
+ .long 0x0 # 32-bit offset
+ .word 0x20 # 16-bit selector
+
+PMODE_ENTRY: # protected mode entry point
+
+ .byte 0x66,0xB8,0x18,0x0 # mov ax, 18h
+ .byte 0x66,0x8E,0xD8 # mov ds, ax
+ .byte 0x66,0x8E,0xC0 # mov es, ax
+ .byte 0x66,0x8E,0xE0 # mov fs, ax
+ .byte 0x66,0x8E,0xE8 # mov gs, ax
+ .byte 0x66,0x8E,0xD0 # mov ss, ax ; Flat mode setup.
+
+ .byte 0xF,0x20,0xE0 # mov eax, cr4
+ .byte 0xF,0xBA,0xE8,0x5 # bts eax, 5
+ .byte 0xF,0x22,0xE0 # mov cr4, eax
+
+ .byte 0xF,0x22,0xD9 # mov cr3, ecx
+
+ .byte 0x8B,0xF2 # mov esi, edx ; Save wakeup buffer address
+
+ .byte 0xB9
+ .long 0xC0000080 # mov ecx, 0c0000080h ; EFER MSR number.
+ .byte 0xF,0x32 # rdmsr ; Read EFER.
+ .byte 0xF,0xBA,0xE8,0x8 # bts eax, 8 ; Set LME=1.
+ .byte 0xF,0x30 # wrmsr ; Write EFER.
+
+ .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Read CR0.
+ .byte 0xF,0xBA,0xE8,0x1F # bts eax, 31 ; Set PG=1.
+ .byte 0xF,0x22,0xC0 # mov cr0, eax ; Write CR0.
+
+LONG_JUMP:
+
+ .byte 0x67,0xEA # far jump
+ .long 0x0 # 32-bit offset
+ .word 0x38 # 16-bit selector
+
+LongModeStart:
+
+ movw $0x30,%ax
+ .byte 0x66
+ movw %ax,%ds
+ .byte 0x66
+ movw %ax,%es
+ .byte 0x66
+ movw %ax,%ss
+
+ movl %esi,%edi
+ addl $LockLocation, %edi
+ movb $NotVacantFlag, %al
+TestLock:
+ xchgb (%edi), %al
+ cmpb $NotVacantFlag, %al
+ jz TestLock
+
+ProgramStack:
+
+ movl %esi,%edi
+ addl $StackSizeLocation, %edi
+ movq (%edi), %rax
+ movl %esi,%edi
+ addl $StackStartAddressLocation, %edi
+ addq (%edi), %rax
+ movq %rax, %rsp
+ movq %rax, (%edi)
+
+Releaselock:
+
+ movb $VacantFlag, %al
+ movl %esi,%edi
+ addl $LockLocation, %edi
+ xchgb (%edi), %al
+
+ #
+ # Call assembly function to initialize FPU.
+ #
+ movabsq $ASM_PFX(InitializeFloatingPointUnits), %rax
+ subq $0x20, %rsp
+ call *%rax
+ addq $0x20, %rsp
+ #
+ # Call C Function
+ #
+ movl %esi,%edi
+ addl $CProcedureLocation, %edi
+ movq (%edi), %rax
+
+ testq %rax, %rax
+ jz GoToSleep
+
+ subq $0x20, %rsp
+ call *%rax
+ addq $0x20, %rsp
+
+GoToSleep:
+ cli
+ hlt
+ jmp .-2
+
+RendezvousFunnelProcEnd:
+
+
+#-------------------------------------------------------------------------------------
+# AsmGetAddressMap (&AddressMap);
+#-------------------------------------------------------------------------------------
+# comments here for definition of address map
+ASM_GLOBAL ASM_PFX(AsmGetAddressMap)
+ASM_PFX(AsmGetAddressMap):
+ movabsq $RendezvousFunnelProcStart, %rax
+ movq %rax, (%rcx)
+ movq $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x08(%rcx)
+ movq $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x10(%rcx)
+ movq $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x18(%rcx)
+ movq $(LongModeStart - RendezvousFunnelProcStart), 0x20(%rcx)
+ movq $(LONG_JUMP - RendezvousFunnelProcStart), 0x28(%rcx)
+ ret
+
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm
new file mode 100644
index 0000000000..2c5a7c9bc2
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm
@@ -0,0 +1,206 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; MpFuncs.asm
+;
+; Abstract:
+;
+; This is the assembly code for Multi-processor S3 support
+;
+;-------------------------------------------------------------------------------
+
+EXTERN InitializeFloatingPointUnits:PROC
+
+VacantFlag Equ 00h
+NotVacantFlag Equ 0ffh
+
+LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+StackStartAddressLocation equ LockLocation + 08h
+StackSizeLocation equ LockLocation + 10h
+CProcedureLocation equ LockLocation + 18h
+GdtrLocation equ LockLocation + 20h
+IdtrLocation equ LockLocation + 2Ah
+BufferStartLocation equ LockLocation + 34h
+Cr3OffsetLocation equ LockLocation + 38h
+
+;-------------------------------------------------------------------------------------
+;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
+.code
+
+RendezvousFunnelProc PROC
+RendezvousFunnelProcStart::
+
+; At this point CS = 0x(vv00) and ip= 0x0.
+
+ db 8ch, 0c8h ; mov ax, cs
+ db 8eh, 0d8h ; mov ds, ax
+ db 8eh, 0c0h ; mov es, ax
+ db 8eh, 0d0h ; mov ss, ax
+ db 33h, 0c0h ; xor ax, ax
+ db 8eh, 0e0h ; mov fs, ax
+ db 8eh, 0e8h ; mov gs, ax
+
+flat32Start::
+
+ db 0BEh
+ dw BufferStartLocation ; mov si, BufferStartLocation
+ db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
+
+ db 0BEh
+ dw Cr3OffsetLocation ; mov si, Cr3Location
+ db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
+
+ db 0BEh
+ dw GdtrLocation ; mov si, GdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
+
+ db 0BEh
+ dw IdtrLocation ; mov si, IdtrProfile
+ db 66h ; db 66h
+ db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
+
+ db 33h, 0C0h ; xor ax, ax
+ db 8Eh, 0D8h ; mov ds, ax
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
+ db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)
+ db 0Fh, 22h, 0C0h ; mov cr0, eax
+
+FLAT32_JUMP::
+
+ db 66h, 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 20h ; 16-bit selector
+
+PMODE_ENTRY:: ; protected mode entry point
+
+ db 66h, 0B8h, 18h, 00h ; mov ax, 18h
+ db 66h, 8Eh, 0D8h ; mov ds, ax
+ db 66h, 8Eh, 0C0h ; mov es, ax
+ db 66h, 8Eh, 0E0h ; mov fs, ax
+ db 66h, 8Eh, 0E8h ; mov gs, ax
+ db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.
+
+ db 0Fh, 20h, 0E0h ; mov eax, cr4
+ db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
+ db 0Fh, 22h, 0E0h ; mov cr4, eax
+
+ db 0Fh, 22h, 0D9h ; mov cr3, ecx
+
+ db 8Bh, 0F2h ; mov esi, edx ; Save wakeup buffer address
+
+ db 0B9h
+ dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
+ db 0Fh, 32h ; rdmsr ; Read EFER.
+ db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
+ db 0Fh, 30h ; wrmsr ; Write EFER.
+
+ db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
+ db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
+ db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
+
+LONG_JUMP::
+
+ db 67h, 0EAh ; far jump
+ dd 0h ; 32-bit offset
+ dw 38h ; 16-bit selector
+
+LongModeStart::
+
+ mov ax, 30h
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ mov edi, esi
+ add edi, LockLocation
+ mov al, NotVacantFlag
+TestLock::
+ xchg byte ptr [edi], al
+ cmp al, NotVacantFlag
+ jz TestLock
+
+ProgramStack::
+
+ mov edi, esi
+ add edi, StackSizeLocation
+ mov rax, qword ptr [edi]
+ mov edi, esi
+ add edi, StackStartAddressLocation
+ add rax, qword ptr [edi]
+ mov rsp, rax
+ mov qword ptr [edi], rax
+
+Releaselock::
+
+ mov al, VacantFlag
+ mov edi, esi
+ add edi, LockLocation
+ xchg byte ptr [edi], al
+
+ ;
+ ; Call assembly function to initialize FPU.
+ ;
+ mov rax, InitializeFloatingPointUnits
+ sub rsp, 20h
+ call rax
+ add rsp, 20h
+
+ ;
+ ; Call C Function
+ ;
+ mov edi, esi
+ add edi, CProcedureLocation
+ mov rax, qword ptr [edi]
+
+ test rax, rax
+ jz GoToSleep
+
+ sub rsp, 20h
+ call rax
+ add rsp, 20h
+
+GoToSleep::
+ cli
+ hlt
+ jmp $-2
+
+RendezvousFunnelProcEnd::
+RendezvousFunnelProc ENDP
+
+
+;-------------------------------------------------------------------------------------
+; AsmGetAddressMap (&AddressMap);
+;-------------------------------------------------------------------------------------
+; comments here for definition of address map
+AsmGetAddressMap PROC
+ mov rax, offset RendezvousFunnelProcStart
+ mov qword ptr [rcx], rax
+ mov qword ptr [rcx+8h], PMODE_ENTRY - RendezvousFunnelProcStart
+ mov qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart
+ mov qword ptr [rcx+18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+ mov qword ptr [rcx+20h], LongModeStart - RendezvousFunnelProcStart
+ mov qword ptr [rcx+28h], LONG_JUMP - RendezvousFunnelProcStart
+ ret
+
+AsmGetAddressMap ENDP
+
+END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
new file mode 100644
index 0000000000..9cee784156
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -0,0 +1,691 @@
+/** @file
+Page Fault (#PF) handler for X64 processors
+
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+#define PAGE_TABLE_PAGES 8
+#define ACC_MAX_BIT BIT3
+LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
+BOOLEAN m1GPageTableSupport = FALSE;
+
+/**
+ 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;
+}
+
+/**
+ 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);
+}
+
+/**
+ 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;
+
+ //
+ // Initialize spin lock
+ //
+ InitializeSpinLock (mPFLock);
+
+ m1GPageTableSupport = Is1GPageSupport ();
+ //
+ // Generate PAE page table for the first 4GB memory space
+ //
+ Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1, 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
+ //
+ PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1));
+ *PTEntry = Pages + PAGE_ATTRIBUTE_BITS;
+ ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
+ //
+ // Set sub-entries number
+ //
+ SetSubEntriesNum (PTEntry, 3);
+
+ //
+ // Add remaining pages to page pool
+ //
+ FreePage = (LIST_ENTRY*)(PTEntry + EFI_PAGE_SIZE / sizeof (*PTEntry));
+ while ((UINTN)FreePage < Pages) {
+ InsertTailList (&mPagePool, FreePage);
+ FreePage += EFI_PAGE_SIZE / sizeof (*FreePage);
+ }
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ //
+ // 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
+ //
+ SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler);
+ }
+
+ //
+ // Additional SMM IDT initialization for SMM stack guard
+ //
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ InitializeIDTSmmStackGuard ();
+ }
+
+ //
+ // Return the address of PML4 (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 *Pml4;
+ UINT64 *Pdpt;
+ UINT64 *Pdt;
+ UINTN Pml4Index;
+ UINTN PdptIndex;
+ UINTN PdtIndex;
+ UINTN MinPml4;
+ UINTN MinPdpt;
+ UINTN MinPdt;
+ UINT64 MinAcc;
+ UINT64 Acc;
+ UINT64 SubEntriesNum;
+ BOOLEAN PML4EIgnore;
+ BOOLEAN PDPTEIgnore;
+ UINT64 *ReleasePageAddress;
+
+ Pml4 = NULL;
+ Pdpt = NULL;
+ Pdt = NULL;
+ MinAcc = (UINT64)-1;
+ MinPml4 = (UINTN)-1;
+ MinPdpt = (UINTN)-1;
+ MinPdt = (UINTN)-1;
+ Acc = 0;
+ ReleasePageAddress = 0;
+
+ //
+ // First, find the leaf entry has the smallest access record value
+ //
+ Pml4 = (UINT64*)(UINTN)(AsmReadCr3 () & 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] & 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] & 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;
+ 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;
+ 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
+ //
+ 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;
+ 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
+ //
+ 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;
+ 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 & 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
+ //
+ Pdpt = (UINT64*)(UINTN)(Pml4[MinPml4] & gPhyMask);
+ SubEntriesNum = GetSubEntriesNum(Pdpt + MinPdpt);
+ if (SubEntriesNum == 0) {
+ //
+ // 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] & 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);
+ 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) {
+ //
+ // 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] & gPhyMask));
+ Pml4[MinPml4] = 0;
+ MinPdpt = (UINTN)-1;
+ continue;
+ }
+ //
+ // Update the sub-entries filed in PML4 entry and exit
+ //
+ SetSubEntriesNum (Pml4 + MinPml4, SubEntriesNum - 1);
+ 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 *Pml4;
+ UINT64 PFAddress;
+ UINTN StartBit;
+ UINTN EndBit;
+ UINT64 PTIndex;
+ UINTN Index;
+ SMM_PAGE_SIZE_TYPE PageSize;
+ UINTN NumOfPages;
+ UINTN PageAttribute;
+ EFI_STATUS Status;
+ UINT64 *UpperEntry;
+
+ //
+ // Set default SMM page attribute
+ //
+ PageSize = SmmPageSize2M;
+ NumOfPages = 1;
+ PageAttribute = 0;
+
+ EndBit = 0;
+ Pml4 = (UINT64*)(AsmReadCr3 () & gPhyMask);
+ PFAddress = AsmReadCr2 ();
+
+ 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 ((EFI_D_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 = Pml4;
+ UpperEntry = NULL;
+ for (StartBit = 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 () | 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] & 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 ((EFI_D_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex]));
+ DEBUG ((EFI_D_ERROR, "New page table overlapped with old page table!\n"));
+ ASSERT (FALSE);
+ }
+ //
+ // Fill the new entry
+ //
+ PageTable[PTIndex] = (PFAddress & gPhyMask & ~((1ull << EndBit) - 1)) |
+ PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
+ if (UpperEntry != NULL) {
+ SetSubEntriesNum (UpperEntry, GetSubEntriesNum (UpperEntry) + 1);
+ }
+ //
+ // 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;
+
+ ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
+
+ AcquireSpinLock (mPFLock);
+
+ PFAddress = AsmReadCr2 ();
+
+ //
+ // If a page fault occurs in SMRAM range, it should be in a SMM stack guard page.
+ //
+ if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
+ (PFAddress >= mCpuHotPlugData.SmrrBase) &&
+ (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
+ DEBUG ((EFI_D_ERROR, "SMM stack overflow!\n"));
+ CpuDeadLoop ();
+ }
+
+ //
+ // If a page fault occurs in SMM range
+ //
+ if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
+ (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
+ if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) {
+ DEBUG ((EFI_D_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 ();
+ }
+ }
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ SmmProfilePFHandler (
+ SystemContext.SystemContextX64->Rip,
+ SystemContext.SystemContextX64->ExceptionData
+ );
+ } else {
+ SmiDefaultPFHandler ();
+ }
+
+ ReleaseSpinLock (mPFLock);
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c
new file mode 100644
index 0000000000..6dbcb086aa
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c
@@ -0,0 +1,67 @@
+/** @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.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+extern UINT32 mSmmRelocationOriginalAddressPtr32;
+extern UINT32 mRebasedFlagAddr32;
+
+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;
+ mRebasedFlagAddr32 = (UINT32)(UINTN)mRebasedFlag;
+
+ 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 complier warning
+ //
+ TempValue = (UINTN)&mSmmRelocationOriginalAddress;
+ mSmmRelocationOriginalAddressPtr32 = (UINT32)TempValue;
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
new file mode 100644
index 0000000000..7e9ac58cb2
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
@@ -0,0 +1,196 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmiEntry.S
+#
+# Abstract:
+#
+# Code template of the SMI handler for a particular processor
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)
+ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
+ASM_GLOBAL ASM_PFX(gSmiCr3)
+ASM_GLOBAL ASM_PFX(gSmiStack)
+ASM_GLOBAL ASM_PFX(gSmbase)
+ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
+
+#
+# Constants relating to PROCESSOR_SMM_DESCRIPTOR
+#
+.equ DSC_OFFSET, 0xfb00
+.equ DSC_GDTPTR, 0x30
+.equ DSC_GDTSIZ, 0x38
+.equ DSC_CS, 14
+.equ DSC_DS, 16
+.equ DSC_SS, 18
+.equ DSC_OTHERSEG, 20
+#
+# Constants relating to CPU State Save Area
+#
+.equ SSM_DR6, 0xffd0
+.equ SSM_DR7, 0xffc8
+
+.equ PROTECT_MODE_CS, 0x08
+.equ PROTECT_MODE_DS, 0x20
+.equ LONG_MODE_CS, 0x38
+.equ TSS_SEGMENT, 0x40
+.equ GDT_SIZE, 0x50
+
+ .text
+
+ASM_PFX(gcSmiHandlerTemplate):
+
+_SmiEntryPoint:
+ #
+ # The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-
+ # bit addressing mode. And that coincidence has been used in the following
+ # "64-bit like" 16-bit code. Be aware that once RDI is referenced as a
+ # base address register, it is actually BX that is referenced.
+ #
+ .byte 0xbb # mov bx, imm16
+ .word _GdtDesc - _SmiEntryPoint + 0x8000
+ #
+ # fix GDT descriptor
+ #
+ .byte 0x2e,0xa1 # mov ax, cs:[offset16]
+ .word DSC_OFFSET + DSC_GDTSIZ
+ .byte 0x48 # dec ax
+ .byte 0x2e
+ movl %eax, (%rdi) # mov cs:[bx], ax
+ .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
+ .word DSC_OFFSET + DSC_GDTPTR
+ .byte 0x2e
+ movw %ax, 2(%rdi)
+ .byte 0x66,0x2e
+ lgdt (%rdi)
+ #
+ # Patch ProtectedMode Segment
+ #
+ .byte 0xb8
+ .word PROTECT_MODE_CS
+ .byte 0x2e
+ movl %eax, -2(%rdi)
+ #
+ # Patch ProtectedMode entry
+ #
+ .byte 0x66, 0xbf # mov edi, SMBASE
+ASM_PFX(gSmbase): .space 4
+ lea ((ProtectedMode - _SmiEntryPoint) + 0x8000)(%edi), %ax
+ .byte 0x2e
+ movw %ax, -6(%rdi)
+ #
+ # Switch into ProtectedMode
+ #
+ movq %cr0, %rbx
+ .byte 0x66
+ andl $0x9ffafff3, %ebx
+ .byte 0x66
+ orl $0x00000023, %ebx
+
+ movq %rbx, %cr0
+ .byte 0x66, 0xea
+ .space 6
+
+_GdtDesc: .space 6
+
+ProtectedMode:
+ movw $PROTECT_MODE_DS, %ax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
+ .byte 0xbc # mov esp, imm32
+ASM_PFX(gSmiStack): .space 4
+ jmp ProtFlatMode
+
+ProtFlatMode:
+ .byte 0xb8
+ASM_PFX(gSmiCr3): .space 4
+ movq %rax, %cr3
+ movl $0x668,%eax # as cr4.PGE is not set here, refresh cr3
+ movq %rax, %cr4 # in PreModifyMtrrs() to flush TLB.
+# Load TSS
+ subl $8, %esp # reserve room in stack
+ sgdt (%rsp)
+ movl 2(%rsp), %eax # eax = GDT base
+ addl $8, %esp
+ movb $0x89, %dl
+ movb %dl, (TSS_SEGMENT + 5)(%rax) # clear busy flag
+ movl $TSS_SEGMENT, %eax
+ ltr %ax
+
+ #
+ # Switch to LongMode
+ #
+ pushq $LONG_MODE_CS # push cs hardcore here
+ call Base # push return address for retf later
+Base:
+ addl $(LongMode - Base), (%rsp) # offset for far retf, seg is the 1st arg
+ movl $0xc0000080, %ecx
+ rdmsr
+ orb $1,%ah
+ wrmsr
+ movq %cr0, %rbx
+ orl $0x080010000, %ebx # enable paging + WP
+ movq %rbx, %cr0
+ retf
+LongMode: # long mode (64-bit code) starts here
+ movabsq $ASM_PFX(gSmiHandlerIdtr), %rax
+ lidt (%rax)
+ lea (DSC_OFFSET)(%rdi), %ebx
+ movw DSC_DS(%rbx), %ax
+ movl %eax,%ds
+ movw DSC_OTHERSEG(%rbx), %ax
+ movl %eax,%es
+ movl %eax,%fs
+ movl %eax,%gs
+ movw DSC_SS(%rbx), %ax
+ movl %eax,%ss
+# jmp _SmiHandler ; instruction is not needed
+
+_SmiHandler:
+ movq (%rsp), %rbx
+ # Save FP registers
+
+ subq $0x208, %rsp
+ .byte 0x48 # FXSAVE64
+ fxsave (%rsp)
+
+ addq $-0x20, %rsp
+
+ movq %rbx, %rcx
+ movabsq $ASM_PFX(CpuSmmDebugEntry), %rax
+ call *%rax
+
+ movq %rbx, %rcx
+ movabsq $ASM_PFX(SmiRendezvous), %rax
+ call *%rax
+
+ movq %rbx, %rcx
+ movabsq $ASM_PFX(CpuSmmDebugExit), %rax
+ call *%rax
+
+ addq $0x20, %rsp
+
+ #
+ # Restore FP registers
+ #
+ .byte 0x48 # FXRSTOR64
+ fxrstor (%rsp)
+
+ rsm
+
+ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
new file mode 100644
index 0000000000..094cf2c3da
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
@@ -0,0 +1,196 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmiEntry.asm
+;
+; Abstract:
+;
+; Code template of the SMI handler for a particular processor
+;
+;-------------------------------------------------------------------------------
+
+;
+; Variables referenced by C code
+;
+EXTERNDEF SmiRendezvous:PROC
+EXTERNDEF CpuSmmDebugEntry:PROC
+EXTERNDEF CpuSmmDebugExit:PROC
+EXTERNDEF gcSmiHandlerTemplate:BYTE
+EXTERNDEF gcSmiHandlerSize:WORD
+EXTERNDEF gSmiCr3:DWORD
+EXTERNDEF gSmiStack:DWORD
+EXTERNDEF gSmbase:DWORD
+EXTERNDEF gSmiHandlerIdtr:FWORD
+
+
+;
+; Constants relating to PROCESSOR_SMM_DESCRIPTOR
+;
+DSC_OFFSET EQU 0fb00h
+DSC_GDTPTR EQU 30h
+DSC_GDTSIZ EQU 38h
+DSC_CS EQU 14
+DSC_DS EQU 16
+DSC_SS EQU 18
+DSC_OTHERSEG EQU 20
+;
+; Constants relating to CPU State Save Area
+;
+SSM_DR6 EQU 0ffd0h
+SSM_DR7 EQU 0ffc8h
+
+PROTECT_MODE_CS EQU 08h
+PROTECT_MODE_DS EQU 20h
+LONG_MODE_CS EQU 38h
+TSS_SEGMENT EQU 40h
+GDT_SIZE EQU 50h
+
+ .code
+
+gcSmiHandlerTemplate LABEL BYTE
+
+_SmiEntryPoint:
+ ;
+ ; The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-
+ ; bit addressing mode. And that coincidence has been used in the following
+ ; "64-bit like" 16-bit code. Be aware that once RDI is referenced as a
+ ; base address register, it is actually BX that is referenced.
+ ;
+ DB 0bbh ; mov bx, imm16
+ DW offset _GdtDesc - _SmiEntryPoint + 8000h ; bx = GdtDesc offset
+; fix GDT descriptor
+ DB 2eh, 0a1h ; mov ax, cs:[offset16]
+ DW DSC_OFFSET + DSC_GDTSIZ
+ DB 48h ; dec ax
+ DB 2eh
+ mov [rdi], eax ; mov cs:[bx], ax
+ DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
+ DW DSC_OFFSET + DSC_GDTPTR
+ DB 2eh
+ mov [rdi + 2], ax ; mov cs:[bx + 2], eax
+ DB 66h, 2eh
+ lgdt fword ptr [rdi] ; lgdt fword ptr cs:[bx]
+; Patch ProtectedMode Segment
+ DB 0b8h ; mov ax, imm16
+ DW PROTECT_MODE_CS ; set AX for segment directly
+ DB 2eh
+ mov [rdi - 2], eax ; mov cs:[bx - 2], ax
+; Patch ProtectedMode entry
+ DB 66h, 0bfh ; mov edi, SMBASE
+gSmbase DD ?
+ lea ax, [edi + (@ProtectedMode - _SmiEntryPoint) + 8000h]
+ DB 2eh
+ mov [rdi - 6], ax ; mov cs:[bx - 6], eax
+; Switch into @ProtectedMode
+ mov rbx, cr0
+ DB 66h
+ and ebx, 9ffafff3h
+ DB 66h
+ or ebx, 00000023h
+
+ mov cr0, rbx
+ DB 66h, 0eah
+ DD ?
+ DW ?
+
+_GdtDesc FWORD ?
+@ProtectedMode:
+ mov ax, PROTECT_MODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ DB 0bch ; mov esp, imm32
+gSmiStack DD ?
+ jmp ProtFlatMode
+
+ProtFlatMode:
+ DB 0b8h ; mov eax, offset gSmiCr3
+gSmiCr3 DD ?
+ mov cr3, rax
+ mov eax, 668h ; 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 fword ptr [rsp]
+ mov eax, [rsp + 2] ; eax = GDT base
+ add esp, 8
+ mov dl, 89h
+ mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
+ mov eax, TSS_SEGMENT
+ ltr ax
+
+; Switch into @LongMode
+ push LONG_MODE_CS ; push cs hardcore here
+ call Base ; push return address for retf later
+Base:
+ add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
+ mov ecx, 0c0000080h
+ rdmsr
+ or ah, 1
+ wrmsr
+ mov rbx, cr0
+ or ebx, 080010000h ; enable paging + WP
+ mov cr0, rbx
+ retf
+@LongMode: ; long mode (64-bit code) starts here
+ mov rax, offset gSmiHandlerIdtr
+ lidt fword ptr [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
+; jmp _SmiHandler ; instruction is not needed
+
+_SmiHandler:
+ mov rbx, [rsp] ; rbx <- CpuIndex
+
+ ;
+ ; Save FP registers
+ ;
+ sub rsp, 208h
+ DB 48h ; FXSAVE64
+ fxsave [rsp]
+
+ add rsp, -20h
+
+ mov rcx, rbx
+ mov rax, CpuSmmDebugEntry
+ call rax
+
+ mov rcx, rbx
+ mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
+ call rax
+
+ mov rcx, rbx
+ mov rax, CpuSmmDebugExit
+ call rax
+
+ add rsp, 20h
+
+ ;
+ ; Restore FP registers
+ ;
+ DB 48h ; FXRSTOR64
+ fxrstor [rsp]
+
+ rsm
+
+gcSmiHandlerSize DW $ - _SmiEntryPoint
+
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S
new file mode 100644
index 0000000000..2ae6f2c32f
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S
@@ -0,0 +1,610 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmiException.S
+#
+# Abstract:
+#
+# Exception handlers used in SM mode
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(SmiPFHandler)
+ASM_GLOBAL ASM_PFX(gSmiMtrrs)
+ASM_GLOBAL ASM_PFX(gcSmiIdtr)
+ASM_GLOBAL ASM_PFX(gcSmiGdtr)
+ASM_GLOBAL ASM_PFX(gcPsd)
+
+ .data
+
+NullSeg: .quad 0 # reserved by architecture
+CodeSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+ProtModeCodeSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+ProtModeSsSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x93
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+DataSeg32:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x93
+ .byte 0xcf # LimitHigh
+ .byte 0 # BaseHigh
+CodeSeg16:
+ .word -1
+ .word 0
+ .byte 0
+ .byte 0x9b
+ .byte 0x8f
+ .byte 0
+DataSeg16:
+ .word -1
+ .word 0
+ .byte 0
+ .byte 0x93
+ .byte 0x8f
+ .byte 0
+CodeSeg64:
+ .word -1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x9b
+ .byte 0xaf # LimitHigh
+ .byte 0 # BaseHigh
+# TSS Segment for X64 specially
+TssSeg:
+ .word TSS_DESC_SIZE - 1 # LimitLow
+ .word 0 # BaseLow
+ .byte 0 # BaseMid
+ .byte 0x89
+ .byte 0x00 # LimitHigh
+ .byte 0 # BaseHigh
+ .long 0 # BaseUpper
+ .long 0 # Reserved
+.equ GDT_SIZE, .- NullSeg
+
+TssDescriptor:
+ .space 104, 0
+.equ TSS_DESC_SIZE, .- TssDescriptor
+
+#
+# This structure serves as a template for all processors.
+#
+ASM_PFX(gcPsd):
+ .ascii "PSDSIG "
+ .word PSD_SIZE
+ .word 2
+ .word 1 << 2
+ .word CODE_SEL
+ .word DATA_SEL
+ .word DATA_SEL
+ .word DATA_SEL
+ .word 0
+ .quad 0
+ .quad 0
+ .quad 0 # fixed in InitializeMpServiceData()
+ .quad NullSeg
+ .long GDT_SIZE
+ .long 0
+ .space 24, 0
+ .quad ASM_PFX(gSmiMtrrs)
+.equ PSD_SIZE, . - ASM_PFX(gcPsd)
+
+#
+# CODE & DATA segments for SMM runtime
+#
+.equ CODE_SEL, CodeSeg64 - NullSeg
+.equ DATA_SEL, DataSeg32 - NullSeg
+.equ CODE32_SEL, CodeSeg32 - NullSeg
+
+ASM_PFX(gcSmiGdtr):
+ .word GDT_SIZE - 1
+ .quad NullSeg
+
+ASM_PFX(gcSmiIdtr):
+ .word IDT_SIZE - 1
+ .quad _SmiIDT
+
+
+#
+# Here is the IDT. There are 32 (not 255) entries in it since only processor
+# generated exceptions will be handled.
+#
+_SmiIDT:
+# The following segment repeats 32 times:
+# No. 1
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 2
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 3
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 4
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 5
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 6
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 7
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 8
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 9
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 10
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 11
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 12
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 13
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 14
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 15
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 16
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 17
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 18
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 19
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 20
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 21
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 22
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 23
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 24
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 25
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 26
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 27
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 28
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 29
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 30
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 31
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+# No. 32
+ .word 0 # Offset 0:15
+ .word CODE_SEL
+ .byte 0 # Unused
+ .byte 0x8e # Interrupt Gate, Present
+ .word 0 # Offset 16:31
+ .quad 0 # Offset 32:63
+
+_SmiIDTEnd:
+
+.equ IDT_SIZE, (_SmiIDTEnd - _SmiIDT)
+
+ .text
+
+#------------------------------------------------------------------------------
+# _SmiExceptionEntryPoints is the collection of exception entry points 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
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
+ASM_PFX(PageFaultIdtHandlerSmmProfile):
+ pushq $0x0e # Page Fault
+ .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8
+ jnz L1
+ pushq (%rsp)
+ movq $0, 8(%rsp)
+L1:
+ pushq %rbp
+ movq %rsp, %rbp
+
+ #
+ # 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 %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
+ movq %ds, %rax
+ pushq %rax
+ movq %es, %rax
+ pushq %rax
+ movq %fs, %rax
+ pushq %rax
+ movq %gs, %rax
+ pushq %rax
+
+## UINT64 Rip;
+ pushq 24(%rbp)
+
+## UINT64 Gdtr[2], Idtr[2];
+ subq $16, %rsp
+ sidt (%rsp)
+ subq $16, %rsp
+ sgdt (%rsp)
+
+## UINT64 Ldtr, Tr;
+ xorq %rax, %rax
+ strw %ax
+ pushq %rax
+ sldtw %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
+ movq %cr3, %rax
+ pushq %rax
+ movq %cr2, %rax
+ pushq %rax
+ xorq %rax, %rax
+ pushq %rax
+ movq %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 0xf, 0xae, 0x7 # 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
+ movabsq $ASM_PFX(SmiPFHandler), %rax
+
+## Prepare parameter and call
+ movq %rsp, %rdx
+ #
+ # Per X64 calling convention, allocate maximum parameter stack space
+ # and make sure RSP is 16-byte aligned
+ #
+ subq $4 * 8 + 8, %rsp
+ call *%rax
+ addq $4 * 8 + 8, %rsp
+ jmp L5
+
+L5:
+## UINT64 ExceptionData;
+ addq $8, %rsp
+
+## FX_SAVE_STATE_X64 FxSaveState;
+
+ movq %rsp, %rsi
+ .byte 0xf, 0xae, 0xe # fxrstor [rsi]
+ addq $512, %rsp
+
+## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+## Skip restoration of DRx registers to support debuggers
+## that set breakpoints in interrupt/exception context
+ addq $8 * 6, %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 gs, rax ; not for gs
+ popq %rax
+ # mov fs, rax ; not for fs
+ # (X64 will not use fs and gs, so we do not restore it)
+ popq %rax
+ movq %rax, %es
+ popq %rax
+ movq %rax, %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
+
+# Enable TF bit after page fault handler runs
+ btsl $8, 40(%rsp) #RFLAGS
+
+ popq %rbp
+ addq $16, %rsp # skip INT# & ErrCode
+ iretq
+
+ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
+ASM_PFX(InitializeIDTSmmStackGuard):
+# If SMM Stack Guard feature is enabled, set the IST field of
+# the interrupt gate for Page Fault Exception to be 1
+#
+ movabsq $_SmiIDT + 14 * 16, %rax
+ movb $1, 4(%rax)
+ ret
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm
new file mode 100644
index 0000000000..ab716450b7
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm
@@ -0,0 +1,413 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmiException.asm
+;
+; Abstract:
+;
+; Exception handlers used in SM mode
+;
+;-------------------------------------------------------------------------------
+
+EXTERNDEF SmiPFHandler:PROC
+EXTERNDEF gSmiMtrrs:QWORD
+EXTERNDEF gcSmiIdtr:FWORD
+EXTERNDEF gcSmiGdtr:FWORD
+EXTERNDEF gcPsd:BYTE
+
+ .const
+
+NullSeg DQ 0 ; reserved by architecture
+CodeSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+ProtModeCodeSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+ProtModeSsSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 93h
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+DataSeg32 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 93h
+ DB 0cfh ; LimitHigh
+ DB 0 ; BaseHigh
+CodeSeg16 LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 9bh
+ DB 8fh
+ DB 0
+DataSeg16 LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 93h
+ DB 8fh
+ DB 0
+CodeSeg64 LABEL QWORD
+ DW -1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 9bh
+ DB 0afh ; LimitHigh
+ DB 0 ; BaseHigh
+; TSS Segment for X64 specially
+TssSeg LABEL QWORD
+ DW TSS_DESC_SIZE - 1 ; LimitLow
+ DW 0 ; BaseLow
+ DB 0 ; BaseMid
+ DB 89h
+ DB 00h ; LimitHigh
+ DB 0 ; BaseHigh
+ DD 0 ; BaseUpper
+ DD 0 ; Reserved
+GDT_SIZE = $ - offset NullSeg
+
+; Create TSS Descriptor just after GDT
+TssDescriptor LABEL BYTE
+ 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 = $ - offset TssDescriptor
+
+;
+; This structure serves as a template for all processors.
+;
+gcPsd LABEL BYTE
+ DB 'PSDSIG '
+ DW PSD_SIZE
+ DW 2
+ DW 1 SHL 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 offset NullSeg
+ DD GDT_SIZE
+ DD 0
+ DB 24 dup (0)
+ DQ offset gSmiMtrrs
+PSD_SIZE = $ - offset gcPsd
+
+;
+; CODE & DATA segments for SMM runtime
+;
+CODE_SEL = offset CodeSeg64 - offset NullSeg
+DATA_SEL = offset DataSeg32 - offset NullSeg
+CODE32_SEL = offset CodeSeg32 - offset NullSeg
+
+gcSmiGdtr LABEL FWORD
+ DW GDT_SIZE - 1
+ DQ offset NullSeg
+
+gcSmiIdtr LABEL FWORD
+ DW IDT_SIZE - 1
+ DQ offset _SmiIDT
+
+ .data
+
+;
+; Here is the IDT. There are 32 (not 255) entries in it since only processor
+; generated exceptions will be handled.
+;
+_SmiIDT:
+REPEAT 32
+ DW 0 ; Offset 0:15
+ DW CODE_SEL ; Segment selector
+ DB 0 ; Unused
+ DB 8eh ; Interrupt Gate, Present
+ DW 0 ; Offset 16:31
+ DQ 0 ; Offset 32:63
+ ENDM
+_SmiIDTEnd:
+
+IDT_SIZE = (offset _SmiIDTEnd - offset _SmiIDT)
+
+ .code
+
+;------------------------------------------------------------------------------
+; _SmiExceptionEntryPoints is the collection of exception entry points 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
+;------------------------------------------------------------------------------
+PageFaultIdtHandlerSmmProfile PROC
+ push 0eh ; Page Fault
+ test spl, 8 ; odd multiple of 8 => ErrCode present
+ jnz @F
+ push [rsp] ; duplicate INT# if no ErrCode
+ mov qword ptr [rsp + 8], 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 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
+
+;; UINT64 Rip;
+ push qword ptr [rbp + 24]
+
+;; UINT64 Gdtr[2], Idtr[2];
+ sub rsp, 16
+ sidt fword ptr [rsp]
+ sub rsp, 16
+ sgdt fword ptr [rsp]
+
+;; 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, 00000111y ;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, 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 @F
+
+@@:
+;; UINT64 ExceptionData;
+ add rsp, 8
+
+;; FX_SAVE_STATE_X64 FxSaveState;
+
+ mov rsi, rsp
+ db 0fh, 0aeh, 00001110y ; 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 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
+
+; Enable TF bit after page fault handler runs
+ bts dword ptr [rsp + 40], 8 ;RFLAGS
+
+ pop rbp
+ add rsp, 16 ; skip INT# & ErrCode
+ iretq
+PageFaultIdtHandlerSmmProfile ENDP
+
+InitializeIDTSmmStackGuard PROC
+;
+; If SMM Stack Guard feature is enabled, set the IST field of
+; the interrupt gate for Page Fault Exception to be 1
+;
+ lea rax, _SmiIDT + 14 * 16
+ mov byte ptr [rax + 4], 1
+ ret
+InitializeIDTSmmStackGuard ENDP
+
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
new file mode 100644
index 0000000000..b53aa45c21
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
@@ -0,0 +1,70 @@
+/** @file
+ SMM CPU misc functions for x64 arch specific.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "PiSmmCpuDxeSmm.h"
+
+/**
+ 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
+ GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
+ ASSERT (GdtTssTables != NULL);
+ 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;
+}
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S
new file mode 100644
index 0000000000..5e352f57c3
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S
@@ -0,0 +1,141 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# 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:
+#
+# SmmInit.S
+#
+# Abstract:
+#
+# Functions for relocating SMBASE's for all processors
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(gSmmCr0)
+ASM_GLOBAL ASM_PFX(gSmmCr3)
+ASM_GLOBAL ASM_PFX(gSmmCr4)
+ASM_GLOBAL ASM_PFX(gSmmJmpAddr)
+ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)
+ASM_GLOBAL ASM_PFX(gcSmmInitSize)
+ASM_GLOBAL ASM_PFX(mRebasedFlagAddr32)
+ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)
+ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete32)
+ASM_GLOBAL ASM_PFX(mSmmRelocationOriginalAddressPtr32)
+ASM_GLOBAL ASM_PFX(gSmmInitStack)
+ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)
+
+
+ .text
+
+ASM_PFX(gcSmiInitGdtr):
+ .word 0
+ .quad 0
+
+SmmStartup:
+ .byte 0x66,0xb8 # mov eax, imm32
+ASM_PFX(gSmmCr3): .space 4
+ movq %rax, %cr3
+ .byte 0x66,0x2e
+ lgdt (ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)
+ .byte 0x66,0xb8 # mov eax, imm32
+ASM_PFX(gSmmCr4): .space 4
+ orb $2, %ah # enable XMM registers access
+ movq %rax, %cr4
+ .byte 0x66
+ movl $0xc0000080,%ecx # IA32_EFER MSR
+ rdmsr
+ orb $1,%ah # set LME bit
+ wrmsr
+ .byte 0x66,0xb8 # mov eax, imm32
+ASM_PFX(gSmmCr0): .space 4
+ movq %rax, %cr0
+ .byte 0x66,0xea # far jmp to long mode
+ASM_PFX(gSmmJmpAddr): .quad LongMode
+LongMode: # long-mode starts here
+ .byte 0x48,0xbc # mov rsp, imm64
+ASM_PFX(gSmmInitStack): .space 8
+ andw $0xfff0, %sp # make sure RSP is 16-byte aligned
+ #
+ # Accoring to X64 calling convention, XMM0~5 are volatile, we need to save
+ # them before calling C-function.
+ #
+ subq $0x60, %rsp
+ movdqa %xmm0, 0x0(%rsp)
+ movdqa %xmm1, 0x10(%rsp)
+ movdqa %xmm2, 0x20(%rsp)
+ movdqa %xmm3, 0x30(%rsp)
+ movdqa %xmm4, 0x40(%rsp)
+ movdqa %xmm5, 0x50(%rsp)
+
+
+ addq $-0x20, %rsp
+ call ASM_PFX(SmmInitHandler)
+ addq $0x20, %rsp
+ #
+ # Restore XMM0~5 after calling C-function.
+ #
+ movdqa 0x0(%rsp), %xmm0
+ movdqa 0x10(%rsp), %xmm1
+ movdqa 0x20(%rsp), %xmm2
+ movdqa 0x30(%rsp), %xmm3
+ movdqa 0x40(%rsp), %xmm4
+ movdqa 0x50(%rsp), %xmm5
+
+ rsm
+
+ASM_PFX(gcSmmInitTemplate):
+
+_SmmInitTemplate:
+ .byte 0x66,0x2e,0x8b,0x2e # mov ebp, cs:[@F]
+ .word L1 - _SmmInitTemplate + 0x8000
+ .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000
+ jmp *%bp # jmp ebp actually
+L1:
+ .quad SmmStartup
+
+ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)
+
+ASM_PFX(SmmRelocationSemaphoreComplete):
+ # Create a simple stack frame to store RAX and the original RSM location
+ pushq %rax # Used to store return address
+ pushq %rax
+
+ # Load the original RSM location onto stack
+ movabsq $ASM_PFX(mSmmRelocationOriginalAddress), %rax
+ movq (%rax), %rax
+ movq %rax, 0x08(%rsp)
+
+ # Update rebase flag
+ movabsq $ASM_PFX(mRebasedFlag), %rax
+ movq (%rax), %rax
+ movb $1, (%rax)
+
+ #restore RAX and return to original RSM location
+ popq %rax
+ retq
+
+#
+# Semaphore code running in 32-bit mode
+#
+ASM_PFX(SmmRelocationSemaphoreComplete32):
+ #
+ # movb $1, ()
+ #
+ .byte 0xc6, 0x05
+ASM_PFX(mRebasedFlagAddr32):
+ .long 0
+ .byte 1
+ #
+ # jmpd ()
+ #
+ .byte 0xff, 0x25
+ASM_PFX(mSmmRelocationOriginalAddressPtr32):
+ .long 0
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm
new file mode 100644
index 0000000000..9182f0293a
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm
@@ -0,0 +1,132 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; SmmInit.Asm
+;
+; Abstract:
+;
+; Functions for relocating SMBASE's for all processors
+;
+;-------------------------------------------------------------------------------
+
+EXTERNDEF SmmInitHandler:PROC
+EXTERNDEF gSmmCr0:DWORD
+EXTERNDEF gSmmCr3:DWORD
+EXTERNDEF gSmmCr4:DWORD
+EXTERNDEF gSmmJmpAddr:QWORD
+EXTERNDEF gcSmmInitTemplate:BYTE
+EXTERNDEF gcSmmInitSize:WORD
+EXTERNDEF mRebasedFlag:PTR BYTE
+EXTERNDEF mSmmRelocationOriginalAddress:QWORD
+EXTERNDEF mRebasedFlagAddr32:DWORD
+EXTERNDEF mSmmRelocationOriginalAddressPtr32:DWORD
+EXTERNDEF gSmmInitStack:QWORD
+EXTERNDEF gcSmiInitGdtr:FWORD
+
+ .code
+
+gcSmiInitGdtr LABEL FWORD
+ DW 0
+ DQ 0
+
+SmmStartup PROC
+ DB 66h, 0b8h ; mov eax, imm32
+gSmmCr3 DD ?
+ mov cr3, rax
+ DB 66h, 2eh
+ lgdt fword ptr [ebp + (offset gcSmiInitGdtr - SmmStartup)]
+ DB 66h, 0b8h ; mov eax, imm32
+gSmmCr4 DD ?
+ or ah, 2 ; enable XMM registers access
+ mov cr4, rax
+ DB 66h
+ mov ecx, 0c0000080h ; IA32_EFER MSR
+ rdmsr
+ or ah, 1 ; set LME bit
+ wrmsr
+ DB 66h, 0b8h ; mov eax, imm32
+gSmmCr0 DD ?
+ mov cr0, rax ; enable protected mode & paging
+ DB 66h, 0eah ; far jmp to long mode
+gSmmJmpAddr DQ @LongMode
+@LongMode: ; long-mode starts here
+ DB 48h, 0bch ; mov rsp, imm64
+gSmmInitStack DQ ?
+ and sp, 0fff0h ; make sure RSP is 16-byte aligned
+ ;
+ ; Accoring to X64 calling convention, XMM0~5 are volatile, we need to save
+ ; them before calling C-function.
+ ;
+ sub rsp, 60h
+ movdqa [rsp], xmm0
+ movdqa [rsp + 10h], xmm1
+ movdqa [rsp + 20h], xmm2
+ movdqa [rsp + 30h], xmm3
+ movdqa [rsp + 40h], xmm4
+ movdqa [rsp + 50h], xmm5
+
+ add rsp, -20h
+ call SmmInitHandler
+ add rsp, 20h
+
+ ;
+ ; Restore XMM0~5 after calling C-function.
+ ;
+ movdqa xmm0, [rsp]
+ movdqa xmm1, [rsp + 10h]
+ movdqa xmm2, [rsp + 20h]
+ movdqa xmm3, [rsp + 30h]
+ movdqa xmm4, [rsp + 40h]
+ movdqa xmm5, [rsp + 50h]
+
+ rsm
+SmmStartup ENDP
+
+gcSmmInitTemplate LABEL BYTE
+
+_SmmInitTemplate PROC
+ DB 66h, 2eh, 8bh, 2eh ; mov ebp, cs:[@F]
+ DW @L1 - _SmmInitTemplate + 8000h
+ DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h
+ jmp bp ; jmp ebp actually
+@L1:
+ DQ SmmStartup
+_SmmInitTemplate ENDP
+
+gcSmmInitSize DW $ - gcSmmInitTemplate
+
+SmmRelocationSemaphoreComplete PROC
+ push rax
+ mov rax, mRebasedFlag
+ mov byte ptr [rax], 1
+ pop rax
+ jmp [mSmmRelocationOriginalAddress]
+SmmRelocationSemaphoreComplete ENDP
+
+;
+; Semaphore code running in 32-bit mode
+;
+SmmRelocationSemaphoreComplete32 PROC
+ ;
+ ; mov byte ptr [], 1
+ ;
+ db 0c6h, 05h
+mRebasedFlagAddr32 dd 0
+ db 1
+ ;
+ ; jmp dword ptr []
+ ;
+ db 0ffh, 25h
+mSmmRelocationOriginalAddressPtr32 dd 0
+SmmRelocationSemaphoreComplete32 ENDP
+
+ END
diff --git a/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
new file mode 100644
index 0000000000..065fb2c24c
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
@@ -0,0 +1,316 @@
+/** @file
+X64 processor specific functions to enable SMM profile.
+
+Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 "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 (1, FALSE);
+
+ //
+ // Fill Page-Table-Level4 (PML4) entry
+ //
+ PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));
+ *PTEntry = Pages | 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] & PHYSICAL_ADDRESS_MASK) == Address)) {
+ *mPFPageUplink[mPFPageIndex] = 0;
+ }
+
+ //
+ // Link & Record the current uplink
+ //
+ *Uplink = Address | 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;
+
+ ASSERT ((PageTable != NULL) && (IsValidPFAddress != NULL));
+
+ //
+ // 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 = BitFieldRead64 (PFAddress, 39, 47);
+ if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
+ // PML4E
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
+ PTIndex = BitFieldRead64 (PFAddress, 30, 38);
+ if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
+ // PDPTE
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
+ PTIndex = BitFieldRead64 (PFAddress, 21, 29);
+ // PD
+ if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
+ //
+ // 2MB page
+ //
+ Address = (UINT64)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
+ if ((Address & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) {
+ Existed = TRUE;
+ }
+ } else {
+ //
+ // 4KB page
+ //
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & 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] & PHYSICAL_ADDRESS_MASK);
+ if ((Address & PHYSICAL_ADDRESS_MASK & ~((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 ();
+ // PML4E
+ PTIndex = BitFieldRead64 (PFAddress, 39, 47);
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
+ // PDPTE
+ PTIndex = BitFieldRead64 (PFAddress, 30, 38);
+ PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
+ // PD
+ PTIndex = BitFieldRead64 (PFAddress, 21, 29);
+ Address = PageTable[PTIndex] & 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] & PHYSICAL_ADDRESS_MASK);
+ for (Index = 0; Index < 512; Index++) {
+ PageTable[Index] = Address | 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/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
new file mode 100644
index 0000000000..32f33139bf
--- /dev/null
+++ b/Core/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
@@ -0,0 +1,105 @@
+/** @file
+X64 processor specific header file to enable SMM profile.
+
+Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+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 _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/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni b/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni
new file mode 100644
index 0000000000..06af9d2ff0
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVector.uni
@@ -0,0 +1,21 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni b/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni
new file mode 100644
index 0000000000..f18a4f0443
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/FixupVtf/ResetVectorExtra.uni
@@ -0,0 +1,17 @@
+// /** @file
+// ResetVector Localized Strings and Content
+//
+// Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module"
+
+
diff --git a/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf b/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf
new file mode 100644
index 0000000000..ed41c3807d
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.inf
@@ -0,0 +1,38 @@
+## @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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# 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 = 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/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb b/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb
new file mode 100644
index 0000000000..5aa733ea59
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/FixupVtf/Vtf.nasmb
@@ -0,0 +1,60 @@
+;------------------------------------------------------------------------------
+; @file
+; First code exectuted by processor after resetting.
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+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/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw
new file mode 100644
index 0000000000..2c6ff655de
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.port80.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw
new file mode 100644
index 0000000000..e34780a3a2
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw
new file mode 100644
index 0000000000..6dfa68eabb
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.ia32.serial.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
new file mode 100644
index 0000000000..72abd6e91c
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
@@ -0,0 +1,36 @@
+## @file
+# Reset Vector binary
+#
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# 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 = ResetVector
+ MODULE_UNI_FILE = ResetVector.uni
+ FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.1
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Binaries.Ia32]
+ RAW|ResetVector.ia32.raw|*
+
+[Binaries.X64]
+ RAW|ResetVector.x64.raw|*
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ ResetVectorExtra.uni
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni
new file mode 100644
index 0000000000..43eba267b6
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Reset Vector binary
+//
+// Reset Vector binary
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Reset Vector binary"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Reset Vector binary"
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw
new file mode 100644
index 0000000000..6c0bcc47eb
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.port80.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw
new file mode 100644
index 0000000000..a78d5b407c
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw
new file mode 100644
index 0000000000..61c71349a8
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.x64.serial.raw
Binary files differ
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni
new file mode 100644
index 0000000000..f18a4f0443
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVectorExtra.uni
@@ -0,0 +1,17 @@
+// /** @file
+// ResetVector Localized Strings and Content
+//
+// Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module"
+
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Build.py b/Core/UefiCpuPkg/ResetVector/Vtf0/Build.py
new file mode 100644
index 0000000000..a645c371b9
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Build.py
@@ -0,0 +1,53 @@
+## @file
+# Automate the process of building the various reset vector types
+#
+# Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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,
+ '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/Core/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc b/Core/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc
new file mode 100644
index 0000000000..b46da27686
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------
+; @file
+; Common macros used in the ResetVector VTF module.
+;
+; Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define ADDR16_OF(x) (0x10000 - fourGigabytes + x)
+%define ADDR_OF(x) (0x100000000 - fourGigabytes + x)
+
+%macro OneTimeCall 1
+ jmp %1
+%1 %+ OneTimerCallReturn:
+%endmacro
+
+%macro OneTimeCallRet 1
+ jmp %1 %+ OneTimerCallReturn
+%endmacro
+
+StartOfResetVectorCode:
+
+%define ADDR_OF_START_OF_RESET_CODE ADDR_OF(StartOfResetVectorCode)
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm
new file mode 100644
index 0000000000..883cef03e0
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/DebugDisabled.asm
@@ -0,0 +1,26 @@
+;------------------------------------------------------------------------------
+; @file
+; Debug disabled
+;
+; Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm
new file mode 100644
index 0000000000..226c49f220
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Init16.asm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------
+; @file
+; 16-bit initialization code
+;
+; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+;
+; @param[out] DI 'BP' to indicate boot-strap processor
+;
+EarlyBspInitReal16:
+ mov di, 'BP'
+ jmp short Main16
+
+;
+; @param[out] DI 'AP' to indicate application processor
+;
+EarlyApInitReal16:
+ mov di, 'AP'
+ jmp short Main16
+
+;
+; Modified: EAX
+;
+; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[out] ESP Initial value of the EAX register (BIST: Built-in Self Test)
+;
+EarlyInit16:
+ ;
+ ; ESP - Initial value of the EAX register (BIST: Built-in Self Test)
+ ;
+ mov esp, eax
+
+ debugInitialize
+
+ OneTimeCallRet EarlyInit16
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
new file mode 100644
index 0000000000..146df600a6
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
@@ -0,0 +1,133 @@
+;------------------------------------------------------------------------------
+; @file
+; Transition from 16 bit real mode into 32 bit flat protected mode
+;
+; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define SEC_DEFAULT_CR0 0x40000023
+%define SEC_DEFAULT_CR4 0x640
+
+BITS 16
+
+;
+; Modified: EAX, EBX
+;
+TransitionFromReal16To32BitFlat:
+
+ debugShowPostCode POSTCODE_16BIT_MODE
+
+ cli
+
+ mov bx, 0xf000
+ mov ds, bx
+
+ mov bx, ADDR16_OF(gdtr)
+
+o32 lgdt [cs:bx]
+
+ mov eax, SEC_DEFAULT_CR0
+ mov cr0, eax
+
+ jmp LINEAR_CODE_SEL:dword ADDR_OF(jumpTo32BitAndLandHere)
+BITS 32
+jumpTo32BitAndLandHere:
+
+ mov eax, SEC_DEFAULT_CR4
+ mov cr4, eax
+
+ debugShowPostCode POSTCODE_32BIT_MODE
+
+ mov ax, LINEAR_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ OneTimeCallRet TransitionFromReal16To32BitFlat
+
+ALIGN 2
+
+gdtr:
+ dw GDT_END - GDT_BASE - 1 ; GDT limit
+ dd ADDR_OF(GDT_BASE)
+
+ALIGN 16
+
+;
+; Macros for GDT entries
+;
+
+%define PRESENT_FLAG(p) (p << 7)
+%define DPL(dpl) (dpl << 5)
+%define SYSTEM_FLAG(s) (s << 4)
+%define DESC_TYPE(t) (t)
+
+; Type: data, expand-up, writable, accessed
+%define DATA32_TYPE 3
+
+; Type: execute, readable, expand-up, accessed
+%define CODE32_TYPE 0xb
+
+; Type: execute, readable, expand-up, accessed
+%define CODE64_TYPE 0xb
+
+%define GRANULARITY_FLAG(g) (g << 7)
+%define DEFAULT_SIZE32(d) (d << 6)
+%define CODE64_FLAG(l) (l << 5)
+%define UPPER_LIMIT(l) (l)
+
+;
+; The Global Descriptor Table (GDT)
+;
+
+GDT_BASE:
+; null descriptor
+NULL_SEL equ $-GDT_BASE
+ DW 0 ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB 0 ; sys flag, dpl, type
+ DB 0 ; limit 19:16, flags
+ DB 0 ; base 31:24
+
+; linear data segment descriptor
+LINEAR_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+
+; linear code segment descriptor
+LINEAR_CODE_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+
+%ifdef ARCH_X64
+; linear code (64-bit) segment descriptor
+LINEAR_CODE64_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+%endif
+
+GDT_END:
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
new file mode 100644
index 0000000000..142d9f3212
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
@@ -0,0 +1,71 @@
+;------------------------------------------------------------------------------
+; @file
+; First code executed by processor after resetting.
+;
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+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
+;
+; GenFv generates code aligned on a 4k boundary which will jump to this
+; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
+; used to wake up the application processors.
+;
+ jmp EarlyApInitReal16
+
+ALIGN 8
+
+ DD 0
+
+;
+; The VTF signature
+;
+; VTF-0 means that the VTF (Volume Top File) code does not require
+; any fixups.
+;
+vtfSignature:
+ DB 'V', 'T', 'F', 0
+
+ALIGN 16
+
+resetVector:
+;
+; Reset Vector
+;
+; This is where the processor will begin execution
+;
+ nop
+ nop
+ jmp EarlyBspInitReal16
+
+ALIGN 16
+
+fourGigabytes:
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm
new file mode 100644
index 0000000000..62e71da3d5
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+; @file
+; Transition from 32 bit flat protected mode into 64 bit flat protected mode
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+;
+; Modified: EAX
+;
+Transition32FlatTo64Flat:
+
+ OneTimeCall SetCr3ForPageTables64
+
+ mov eax, cr4
+ bts eax, 5 ; enable PAE
+ mov cr4, eax
+
+ mov ecx, 0xc0000080
+ rdmsr
+ bts eax, 8 ; set LME
+ wrmsr
+
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax ; enable paging
+
+ jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)
+BITS 64
+jumpTo64BitAndLandHere:
+
+ debugShowPostCode POSTCODE_64BIT_MODE
+
+ OneTimeCallRet Transition32FlatTo64Flat
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm
new file mode 100644
index 0000000000..2e16e71f6a
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm
@@ -0,0 +1,30 @@
+;------------------------------------------------------------------------------
+; @file
+; Sets the CR3 register for 64-bit paging
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+;
+; 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/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm
new file mode 100644
index 0000000000..d0c2d8c39c
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForBfvBase.asm
@@ -0,0 +1,86 @@
+;------------------------------------------------------------------------------
+; @file
+; Search for the Boot Firmware Volume (BFV) base address
+;
+; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+;#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
+; { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }
+%define FFS_GUID_DWORD0 0x8c8ce578
+%define FFS_GUID_DWORD1 0x4f1c8a3d
+%define FFS_GUID_DWORD2 0x61893599
+%define FFS_GUID_DWORD3 0xd32dc385
+
+BITS 32
+
+;
+; Modified: EAX, EBX
+; Preserved: EDI, ESP
+;
+; @param[out] EBP Address of Boot Firmware Volume (BFV)
+;
+Flat32SearchForBfvBase:
+
+ xor eax, eax
+searchingForBfvHeaderLoop:
+ ;
+ ; We check for a firmware volume at every 4KB address in the top 16MB
+ ; just below 4GB. (Addresses at 0xffHHH000 where H is any hex digit.)
+ ;
+ sub eax, 0x1000
+ cmp eax, 0xff000000
+ jb searchedForBfvHeaderButNotFound
+
+ ;
+ ; Check FFS GUID
+ ;
+ cmp dword [eax + 0x10], FFS_GUID_DWORD0
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x14], FFS_GUID_DWORD1
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x18], FFS_GUID_DWORD2
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x1c], FFS_GUID_DWORD3
+ jne searchingForBfvHeaderLoop
+
+ ;
+ ; Check FV Length
+ ;
+ cmp dword [eax + 0x24], 0
+ jne searchingForBfvHeaderLoop
+ mov ebx, eax
+ add ebx, dword [eax + 0x20]
+ jnz searchingForBfvHeaderLoop
+
+ jmp searchedForBfvHeaderAndItWasFound
+
+searchedForBfvHeaderButNotFound:
+ ;
+ ; Hang if the SEC entry point was not found
+ ;
+ debugShowPostCode POSTCODE_BFV_NOT_FOUND
+
+ ;
+ ; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
+ ; for debugging purposes.
+ ;
+ mov eax, 0xBFBFBFBF
+ mov ebp, eax
+ jmp $
+
+searchedForBfvHeaderAndItWasFound:
+ mov ebp, eax
+
+ debugShowPostCode POSTCODE_BFV_FOUND
+
+ OneTimeCallRet Flat32SearchForBfvBase
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm
new file mode 100644
index 0000000000..6206b44485
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm
@@ -0,0 +1,200 @@
+;------------------------------------------------------------------------------
+; @file
+; Search for the SEC Core entry point
+;
+; Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+%define EFI_FV_FILETYPE_SECURITY_CORE 0x03
+
+;
+; Modified: EAX, EBX, ECX, EDX
+; Preserved: EDI, EBP, ESP
+;
+; @param[in] EBP Address of Boot Firmware Volume (BFV)
+; @param[out] ESI SEC Core Entry Point Address
+;
+Flat32SearchForSecEntryPoint:
+
+ ;
+ ; Initialize EBP and ESI to 0
+ ;
+ xor ebx, ebx
+ mov esi, ebx
+
+ ;
+ ; Pass over the BFV header
+ ;
+ mov eax, ebp
+ mov bx, [ebp + 0x30]
+ add eax, ebx
+ jc secEntryPointWasNotFound
+
+ jmp searchingForFfsFileHeaderLoop
+
+moveForwardWhileSearchingForFfsFileHeaderLoop:
+ ;
+ ; Make forward progress in the search
+ ;
+ inc eax
+ jc secEntryPointWasNotFound
+
+searchingForFfsFileHeaderLoop:
+ test eax, eax
+ jz secEntryPointWasNotFound
+
+ ;
+ ; Ensure 8 byte alignment
+ ;
+ add eax, 7
+ jc secEntryPointWasNotFound
+ and al, 0xf8
+
+ ;
+ ; Look to see if there is an FFS file at eax
+ ;
+ mov bl, [eax + 0x17]
+ test bl, 0x20
+ jz moveForwardWhileSearchingForFfsFileHeaderLoop
+ mov ecx, [eax + 0x14]
+ and ecx, 0x00ffffff
+ or ecx, ecx
+ jz moveForwardWhileSearchingForFfsFileHeaderLoop
+ add ecx, eax
+ jz jumpSinceWeFoundTheLastFfsFile
+ jc moveForwardWhileSearchingForFfsFileHeaderLoop
+jumpSinceWeFoundTheLastFfsFile:
+
+ ;
+ ; There seems to be a valid file at eax
+ ;
+ cmp byte [eax + 0x12], EFI_FV_FILETYPE_SECURITY_CORE ; Check File Type
+ jne readyToTryFfsFileAtEcx
+
+fileTypeIsSecCore:
+ OneTimeCall GetEntryPointOfFfsFile
+ test eax, eax
+ jnz doneSeachingForSecEntryPoint
+
+readyToTryFfsFileAtEcx:
+ ;
+ ; Try the next FFS file at ECX
+ ;
+ mov eax, ecx
+ jmp searchingForFfsFileHeaderLoop
+
+secEntryPointWasNotFound:
+ xor eax, eax
+
+doneSeachingForSecEntryPoint:
+ mov esi, eax
+
+ test esi, esi
+ jnz secCoreEntryPointWasFound
+
+secCoreEntryPointWasNotFound:
+ ;
+ ; Hang if the SEC entry point was not found
+ ;
+ debugShowPostCode POSTCODE_SEC_NOT_FOUND
+ jz $
+
+secCoreEntryPointWasFound:
+ debugShowPostCode POSTCODE_SEC_FOUND
+
+ OneTimeCallRet Flat32SearchForSecEntryPoint
+
+%define EFI_SECTION_PE32 0x10
+%define EFI_SECTION_TE 0x12
+
+;
+; Input:
+; EAX - Start of FFS file
+; ECX - End of FFS file
+;
+; Output:
+; EAX - Entry point of PE32 (or 0 if not found)
+;
+; Modified:
+; EBX
+;
+GetEntryPointOfFfsFile:
+ test eax, eax
+ jz getEntryPointOfFfsFileErrorReturn
+ add eax, 0x18 ; EAX = Start of section
+
+getEntryPointOfFfsFileLoopForSections:
+ cmp eax, ecx
+ jae getEntryPointOfFfsFileErrorReturn
+
+ cmp byte [eax + 3], EFI_SECTION_PE32
+ je getEntryPointOfFfsFileFoundPe32Section
+
+ cmp byte [eax + 3], EFI_SECTION_TE
+ je getEntryPointOfFfsFileFoundTeSection
+
+ ;
+ ; The section type was not PE32 or TE, so move to next section
+ ;
+ mov ebx, dword [eax]
+ and ebx, 0x00ffffff
+ add eax, ebx
+ jc getEntryPointOfFfsFileErrorReturn
+
+ ;
+ ; Ensure that FFS section is 32-bit aligned
+ ;
+ add eax, 3
+ jc getEntryPointOfFfsFileErrorReturn
+ and al, 0xfc
+ jmp getEntryPointOfFfsFileLoopForSections
+
+getEntryPointOfFfsFileFoundPe32Section:
+ add eax, 4 ; EAX = Start of PE32 image
+
+ cmp word [eax], 'MZ'
+ jne getEntryPointOfFfsFileErrorReturn
+ movzx ebx, word [eax + 0x3c]
+ add ebx, eax
+
+ ; if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)
+ cmp dword [ebx], `PE\x00\x00`
+ jne getEntryPointOfFfsFileErrorReturn
+
+ ; *EntryPoint = (VOID *)((UINTN)Pe32Data +
+ ; (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ 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
+
+getEntryPointOfFfsFileReturn:
+ OneTimeCallRet GetEntryPointOfFfsFile
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Main.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Main.asm
new file mode 100644
index 0000000000..ebfb9015d4
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Main.asm
@@ -0,0 +1,106 @@
+;------------------------------------------------------------------------------
+; @file
+; Main routine of the pre-SEC code up through the jump into SEC
+;
+; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+;
+; Modified: EBX, ECX, EDX, EBP
+;
+; @param[in,out] RAX/EAX Initial value of the EAX register
+; (BIST: Built-in Self Test)
+; @param[in,out] DI 'BP': boot-strap processor, or
+; 'AP': application processor
+; @param[out] RBP/EBP Address of Boot Firmware Volume (BFV)
+;
+; @return None This routine jumps to SEC and does not return
+;
+Main16:
+ OneTimeCall EarlyInit16
+
+ ;
+ ; Transition the processor from 16-bit real mode to 32-bit flat mode
+ ;
+ OneTimeCall TransitionFromReal16To32BitFlat
+
+BITS 32
+
+ ;
+ ; Search for the Boot Firmware Volume (BFV)
+ ;
+ OneTimeCall Flat32SearchForBfvBase
+
+ ;
+ ; EBP - Start of BFV
+ ;
+
+ ;
+ ; Search for the SEC entry point
+ ;
+ OneTimeCall Flat32SearchForSecEntryPoint
+
+ ;
+ ; ESI - SEC Core entry point
+ ; EBP - Start of BFV
+ ;
+
+%ifdef ARCH_IA32
+
+ ;
+ ; Restore initial EAX value into the EAX register
+ ;
+ mov eax, esp
+
+ ;
+ ; Jump to the 32-bit SEC entry point
+ ;
+ jmp esi
+
+%else
+
+ ;
+ ; Transition the processor from 32-bit flat mode to 64-bit flat mode
+ ;
+ OneTimeCall Transition32FlatTo64Flat
+
+BITS 64
+
+ ;
+ ; Some values were calculated in 32-bit mode. Make sure the upper
+ ; 32-bits of 64-bit registers are zero for these values.
+ ;
+ mov rax, 0x00000000ffffffff
+ and rsi, rax
+ and rbp, rax
+ and rsp, rax
+
+ ;
+ ; RSI - SEC Core entry point
+ ; RBP - Start of BFV
+ ;
+
+ ;
+ ; Restore initial EAX value into the RAX register
+ ;
+ mov rax, rsp
+
+ ;
+ ; Jump to the 64-bit SEC entry point
+ ;
+ jmp rsi
+
+%endif
+
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm
new file mode 100644
index 0000000000..4b13c4860b
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Port80Debug.asm
@@ -0,0 +1,28 @@
+;------------------------------------------------------------------------------
+; @file
+; Port 0x80 debug support macros
+;
+; Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+ mov al, %1
+ out 0x80, al
+%endmacro
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc b/Core/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc
new file mode 100644
index 0000000000..62eda5d992
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/PostCodes.inc
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+; @file
+; Definitions of POST CODES for the reset vector module
+;
+; Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define POSTCODE_16BIT_MODE 0x16
+%define POSTCODE_32BIT_MODE 0x32
+%define POSTCODE_64BIT_MODE 0x64
+
+%define POSTCODE_BFV_NOT_FOUND 0xb0
+%define POSTCODE_BFV_FOUND 0xb1
+
+%define POSTCODE_SEC_NOT_FOUND 0xf0
+%define POSTCODE_SEC_FOUND 0xf1
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt b/Core/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt
new file mode 100644
index 0000000000..e6e5b54243
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt
@@ -0,0 +1,41 @@
+
+=== HOW TO USE VTF0 ===
+
+Add this line to your FDF FV section:
+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:
+[Rule.Common.SEC.RESET_VECTOR]
+ FILE RAW = $(NAMED_GUID) {
+ RAW RAW |.raw
+ }
+
+=== VTF0 Boot Flow ===
+
+1. Transition to IA32 flat mode
+2. Locate BFV (Boot Firmware Volume) by checking every 4kb boundary
+3. Locate SEC image
+4. X64 VTF0 transitions to X64 mode
+5. Call SEC image entry point
+
+== VTF0 SEC input parameters ==
+
+All inputs to SEC image are register based:
+EAX/RAX - Initial value of the EAX register (BIST: Built-in Self Test)
+DI - 'BP': boot-strap processor, or 'AP': application processor
+EBP/RBP - Pointer to the start of the Boot Firmware Volume
+
+=== HOW TO BUILD VTF0 ===
+
+Dependencies:
+* Python 2.5~2.7
+* Nasm 2.03 or newer
+
+To rebuild the VTF0 binaries:
+1. Change to VTF0 source dir: UefiCpuPkg/ResetVector/Vtf0
+2. nasm and python should be in executable path
+3. Run this command:
+ python Build.py
+4. Binaries output will be in UefiCpuPkg/ResetVector/Vtf0/Bin
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni b/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni
new file mode 100644
index 0000000000..3fcc3f084c
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVector.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Reset Vector
+//
+// Reset Vector
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Reset Vector"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Reset Vector"
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni b/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni
new file mode 100644
index 0000000000..f18a4f0443
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/ResetVectorExtra.uni
@@ -0,0 +1,17 @@
+// /** @file
+// ResetVector Localized Strings and Content
+//
+// Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME #language en-US "ResetVector module"
+
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm
new file mode 100644
index 0000000000..ebd0910f4a
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/SerialDebug.asm
@@ -0,0 +1,132 @@
+;------------------------------------------------------------------------------
+; @file
+; Serial port debug support macros
+;
+; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+;//---------------------------------------------
+;// UART Register Offsets
+;//---------------------------------------------
+%define BAUD_LOW_OFFSET 0x00
+%define BAUD_HIGH_OFFSET 0x01
+%define IER_OFFSET 0x01
+%define LCR_SHADOW_OFFSET 0x01
+%define FCR_SHADOW_OFFSET 0x02
+%define IR_CONTROL_OFFSET 0x02
+%define FCR_OFFSET 0x02
+%define EIR_OFFSET 0x02
+%define BSR_OFFSET 0x03
+%define LCR_OFFSET 0x03
+%define MCR_OFFSET 0x04
+%define LSR_OFFSET 0x05
+%define MSR_OFFSET 0x06
+
+;//---------------------------------------------
+;// UART Register Bit Defines
+;//---------------------------------------------
+%define LSR_TXRDY 0x20
+%define LSR_RXDA 0x01
+%define DLAB 0x01
+
+; UINT16 gComBase = 0x3f8;
+; UINTN gBps = 115200;
+; UINT8 gData = 8;
+; UINT8 gStop = 1;
+; UINT8 gParity = 0;
+; UINT8 gBreakSet = 0;
+
+%define DEFAULT_COM_BASE 0x3f8
+%define DEFAULT_BPS 115200
+%define DEFAULT_DATA 8
+%define DEFAULT_STOP 1
+%define DEFAULT_PARITY 0
+%define DEFAULT_BREAK_SET 0
+
+%define SERIAL_DEFAULT_LCR ( \
+ (DEFAULT_BREAK_SET << 6) | \
+ (DEFAULT_PARITY << 3) | \
+ (DEFAULT_STOP << 2) | \
+ (DEFAULT_DATA - 5) \
+ )
+
+%define SERIAL_PORT_IO_BASE_ADDRESS DEFAULT_COM_BASE
+
+%macro inFromSerialPort 1
+ mov dx, (SERIAL_PORT_IO_BASE_ADDRESS + %1)
+ in al, dx
+%endmacro
+
+%macro waitForSerialTxReady 0
+
+%%waitingForTx:
+ inFromSerialPort LSR_OFFSET
+ test al, LSR_TXRDY
+ jz %%waitingForTx
+
+%endmacro
+
+%macro outToSerialPort 2
+ mov dx, (SERIAL_PORT_IO_BASE_ADDRESS + %1)
+ mov al, %2
+ out dx, al
+%endmacro
+
+%macro debugShowCharacter 1
+ waitForSerialTxReady
+ outToSerialPort 0, %1
+%endmacro
+
+%macro debugShowHexDigit 1
+ %if (%1 < 0xa)
+ debugShowCharacter BYTE ('0' + (%1))
+ %else
+ debugShowCharacter BYTE ('a' + ((%1) - 0xa))
+ %endif
+%endmacro
+
+%macro debugNewline 0
+ debugShowCharacter `\r`
+ debugShowCharacter `\n`
+%endmacro
+
+%macro debugShowPostCode 1
+ debugShowHexDigit (((%1) >> 4) & 0xf)
+ debugShowHexDigit ((%1) & 0xf)
+ debugNewline
+%endmacro
+
+BITS 16
+
+%macro debugInitialize 0
+ jmp real16InitDebug
+real16InitDebugReturn:
+%endmacro
+
+real16InitDebug:
+ ;
+ ; Set communications format
+ ;
+ outToSerialPort LCR_OFFSET, ((DLAB << 7) | SERIAL_DEFAULT_LCR)
+
+ ;
+ ; Configure baud rate
+ ;
+ outToSerialPort BAUD_HIGH_OFFSET, ((115200 / DEFAULT_BPS) >> 8)
+ outToSerialPort BAUD_LOW_OFFSET, ((115200 / DEFAULT_BPS) & 0xff)
+
+ ;
+ ; Switch back to bank 0
+ ;
+ outToSerialPort LCR_OFFSET, SERIAL_DEFAULT_LCR
+
+ jmp real16InitDebugReturn
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py b/Core/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py
new file mode 100644
index 0000000000..a70ce7501d
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py
@@ -0,0 +1,26 @@
+## @file
+# Apply fixup to VTF binary image for FFS Raw section
+#
+# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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]
+
+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/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf b/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf
new file mode 100644
index 0000000000..41aba45a14
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.inf
@@ -0,0 +1,36 @@
+## @file
+# Reset Vector
+#
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# 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 = 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/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb b/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb
new file mode 100644
index 0000000000..f4a29e8d89
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------
+; @file
+; This file includes all other code files to assemble the reset vector code
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+;
+; 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 <Base.h>
+ #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."
+ %endif
+%elifdef ARCH_X64
+%else
+ %error "Either ARCH_IA32 or ARCH_X64 must be defined."
+%endif
+
+%include "CommonMacros.inc"
+
+%include "PostCodes.inc"
+
+%ifdef ARCH_X64
+%include "X64/PageTables.asm"
+%endif
+
+%ifdef DEBUG_PORT80
+ %include "Port80Debug.asm"
+%elifdef DEBUG_SERIAL
+ %include "SerialDebug.asm"
+%else
+ %include "DebugDisabled.asm"
+%endif
+
+%include "Ia32/SearchForBfvBase.asm"
+%include "Ia32/SearchForSecEntry.asm"
+
+%ifdef ARCH_X64
+%include "Ia32/Flat32ToFlat64.asm"
+%include "Ia32/PageTables64.asm"
+%endif
+
+%include "Ia16/Real16ToFlat32.asm"
+%include "Ia16/Init16.asm"
+
+%include "Main.asm"
+
+%include "Ia16/ResetVectorVtf0.asm"
+
diff --git a/Core/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm b/Core/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm
new file mode 100644
index 0000000000..3d703c74f6
--- /dev/null
+++ b/Core/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm
@@ -0,0 +1,78 @@
+;------------------------------------------------------------------------------
+; @file
+; Emits Page Tables for 1:1 mapping of the addresses 0 - 0x100000000 (4GB)
+;
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; 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
+
+%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/Core/UefiCpuPkg/SecCore/FindPeiCore.c b/Core/UefiCpuPkg/SecCore/FindPeiCore.c
new file mode 100644
index 0000000000..60ccaa9667
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/FindPeiCore.c
@@ -0,0 +1,198 @@
+/** @file
+ Locate the entry point for the PEI Core
+
+ Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+
+#include "SecMain.h"
+
+/**
+ Find core image base.
+
+ @param BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param SecCoreImageBase The base address of the SEC core image.
+ @param PeiCoreImageBase The base address of the PEI core image.
+
+**/
+EFI_STATUS
+EFIAPI
+FindImageBase (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ *SecCoreImageBase = 0;
+ *PeiCoreImageBase = 0;
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ 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 SEC Core / PEI Core files
+ //
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
+ File->Type != EFI_FV_FILETYPE_PEI_CORE) {
+ 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 == EFI_FV_FILETYPE_SECURITY_CORE) {
+ if (IS_SECTION2 (Section)) {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ } else {
+ if (IS_SECTION2 (Section)) {
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ }
+ break;
+ }
+ }
+
+ //
+ // Both SEC Core and PEI Core images found
+ //
+ if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 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 BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param PeiCoreEntryPoint The entry point of the PEI core.
+
+**/
+VOID
+EFIAPI
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ //
+ // Find SEC Core and PEI Core image base
+ //
+ Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);
+ 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);
+
+ //
+ // 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/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.asm16 b/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.asm16
new file mode 100644
index 0000000000..d90613c4d0
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.asm16
@@ -0,0 +1,106 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; ResetVec.asm
+;
+; Abstract:
+;
+; Reset Vector Data structure
+; This structure is located at 0xFFFFFFC0
+;
+;------------------------------------------------------------------------------
+
+ .model tiny
+ .686p
+ .stack 0h
+ .code
+
+;
+; The layout of this file is fixed. The build tool makes assumption of the layout.
+;
+
+ ORG 0h
+;
+; Reserved
+;
+ReservedData DD 0eeeeeeeeh, 0eeeeeeeeh
+
+ ORG 10h
+;
+; This is located at 0xFFFFFFD0h
+;
+ mov di, "AP"
+ jmp ApStartup
+
+ ORG 20h
+;
+; 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.
+;
+InterruptHandler PROC
+ jmp $
+ iret
+InterruptHandler ENDP
+
+ ORG 30h
+;
+; 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
+
+
+ ORG 38h
+;
+; 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
+
+ ORG 3ch
+;
+; 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.
+;
+
+ END
diff --git a/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb b/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb
new file mode 100644
index 0000000000..2fcdc85e47
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/Ia32/ResetVec.nasmb
@@ -0,0 +1,103 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; 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/Core/UefiCpuPkg/SecCore/SecCore.inf b/Core/UefiCpuPkg/SecCore/SecCore.inf
new file mode 100644
index 0000000000..bf08a4cc49
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/SecCore.inf
@@ -0,0 +1,72 @@
+## @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 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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 = 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 IPF EBC
+#
+
+[Sources]
+ SecMain.c
+ SecMain.h
+ FindPeiCore.c
+
+[Sources.IA32]
+ Ia32/ResetVec.asm16 | MSFT
+ Ia32/ResetVec.asm16 | INTEL
+ Ia32/ResetVec.nasmb | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PlatformSecLib
+ PcdLib
+ DebugAgentLib
+ UefiCpuLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ CpuExceptionHandlerLib
+ ReportStatusCodeLib
+
+[Ppis]
+ gEfiSecPlatformInformationPpiGuid ## PRODUCES
+ gEfiTemporaryRamDonePpiGuid ## PRODUCES
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ SecCoreExtra.uni
diff --git a/Core/UefiCpuPkg/SecCore/SecCore.uni b/Core/UefiCpuPkg/SecCore/SecCore.uni
new file mode 100644
index 0000000000..bd43c8b753
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/SecCore.uni
@@ -0,0 +1,24 @@
+// /** @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.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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/Core/UefiCpuPkg/SecCore/SecCoreExtra.uni b/Core/UefiCpuPkg/SecCore/SecCoreExtra.uni
new file mode 100644
index 0000000000..c4bd4da20e
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/SecCoreExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// SecCore Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"SEC Core Module"
diff --git a/Core/UefiCpuPkg/SecCore/SecMain.c b/Core/UefiCpuPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..ec252cf719
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/SecMain.c
@@ -0,0 +1,295 @@
+/** @file
+ C functions in SEC
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 "SecMain.h"
+
+EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = {
+ SecTemporaryRamDone
+};
+
+EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { SecPlatformInformation };
+
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
+ {
+ 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
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ );
+
+/**
+
+ 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
+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)(0x100000000ULL - (UINTN) BootFirmwareVolume);
+ 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);
+}
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+ UINT32 Index;
+ EFI_PEI_PPI_DESCRIPTOR *AllSecPpiList;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+ AllSecPpiList = (EFI_PEI_PPI_DESCRIPTOR *) SecCoreData->PeiTemporaryRamBase;
+ //
+ // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);
+ if (PeiCoreEntryPoint == NULL)
+ {
+ CpuDeadLoop ();
+ }
+
+ //
+ // Perform platform specific initialization before entering PeiCore.
+ //
+ PpiList = SecPlatformMain (SecCoreData);
+ if (PpiList != NULL) {
+ //
+ // 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);
+ } else {
+ //
+ // No addition PPI, PpiList directly point to the common PPI list.
+ //
+ PpiList = &mPeiSecPlatformInformationPpi[0];
+ }
+
+ //
+ // 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.
+ //
+ return;
+}
+
+/**
+ 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;
+
+ //
+ // 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/Core/UefiCpuPkg/SecCore/SecMain.h b/Core/UefiCpuPkg/SecCore/SecMain.h
new file mode 100644
index 0000000000..05175d299d
--- /dev/null
+++ b/Core/UefiCpuPkg/SecCore/SecMain.h
@@ -0,0 +1,109 @@
+/** @file
+ Master header file for SecCore.
+
+ Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 _SEC_CORE_H_
+#define _SEC_CORE_H_
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TemporaryRamDone.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PlatformSecLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+
+#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
+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 BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param PeiCoreEntryPoint Point to the PEI core entry point.
+
+**/
+VOID
+EFIAPI
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ 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
+ );
+
+#endif
diff --git a/Core/UefiCpuPkg/UefiCpuPkg.dec b/Core/UefiCpuPkg/UefiCpuPkg.dec
new file mode 100644
index 0000000000..16637dfdc1
--- /dev/null
+++ b/Core/UefiCpuPkg/UefiCpuPkg.dec
@@ -0,0 +1,210 @@
+## @file UefiCpuPkg.dec
+# This Package provides UEFI compatible CPU modules and libraries.
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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_UNI_FILE = UefiCpuPkg.uni
+ PACKAGE_GUID = 2171df9b-0d39-45aa-ac37-2de190010d23
+ PACKAGE_VERSION = 0.3
+
+[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
+
+ ## @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
+
+[Guids]
+ gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}
+
+[Protocols]
+ ## Include/Protocol/SmmCpuService.h
+ gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
+
+#
+# [Error.gUefiCpuPkgTokenSpaceGuid]
+# 0x80000001 | Invalid value provided.
+#
+
+[PcdsFeatureFlag]
+ ## Indicates if SMM Profile will be enabled.
+ # If enabled, instruction executions in and data accesses to memory outside of SMRAM will be logged.
+ # This PCD is only for validation purpose. It should be set to false in production.<BR><BR>
+ # TRUE - SMM Profile will be enabled.<BR>
+ # FALSE - SMM Profile will be disabled.<BR>
+ # @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.<BR><BR>
+ # TRUE - the SMM profile log buffer is a ring buffer.<BR>
+ # FALSE - the SMM profile log buffer is a normal buffer.<BR>
+ # @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.<BR>
+ # FALSE - SMM Startup AP in a non-blocking fashion.<BR>
+ # @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 which eases debugging.<BR><BR>
+ # TRUE - SMM Stack Guard will be enabled.<BR>
+ # FALSE - SMM Stack Guard will be disabled.<BR>
+ # @Prompt Enable SMM Stack Guard.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard|FALSE|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.<BR><BR>
+ # TRUE - BSP election in SMM will be enabled.<BR>
+ # FALSE - BSP election in SMM will be disabled.<BR>
+ # @Prompt Enable BSP election in SMM.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|TRUE|BOOLEAN|0x32132106
+
+ ## Indicates if CPU SMM hot-plug will be enabled.<BR><BR>
+ # TRUE - SMM CPU hot-plug will be enabled.<BR>
+ # FALSE - SMM CPU hot-plug will be disabled.<BR>
+ # @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.<BR><BR>
+ # TRUE - SMM Debug will be enabled.<BR>
+ # FALSE - SMM Debug will be disabled.<BR>
+ # @Prompt Enable SMM Debug.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|FALSE|BOOLEAN|0x1000001B
+
+ ## Indicates if lock SMM Feature Control MSR.<BR><BR>
+ # TRUE - SMM Feature Control MSR will be locked.<BR>
+ # FALSE - SMM Feature Control MSR will not be locked.<BR>
+ # @Prompt Lock SMM Feature Control MSR.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock|TRUE|BOOLEAN|0x3213210B
+
+[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 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 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.<BR><BR>
+ # TRUE - SMM Code Access Check will be enabled.<BR>
+ # FALSE - SMM Code Access Check will be disabled.<BR>
+ # @Prompt SMM Code Access Check.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable|TRUE|BOOLEAN|0x60000013
+
+ ## Indicates the CPU synchronization method used when processing an SMI.
+ # 0x00 - Traditional CPU synchronization method.<BR>
+ # 0x01 - Relaxed CPU synchronization method.<BR>
+ # @Prompt SMM CPU Synchronization Method.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x00|UINT8|0x60000014
+
+ ## 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
+
+[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 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.<BR><BR>
+ # 1: Place AP in the Hlt-Loop state.<BR>
+ # 2: Place AP in the Mwait-Loop state.<BR>
+ # 3: Place AP in the Run-Loop state.<BR>
+ # @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.<BR><BR>
+ # @Prompt The specified AP target C-state for Mwait.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0|UINT8|0x00000007
+
+[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
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ UefiCpuPkgExtra.uni
diff --git a/Core/UefiCpuPkg/UefiCpuPkg.dsc b/Core/UefiCpuPkg/UefiCpuPkg.dsc
new file mode 100644
index 0000000000..b35f41b1ed
--- /dev/null
+++ b/Core/UefiCpuPkg/UefiCpuPkg.dsc
@@ -0,0 +1,126 @@
+## @file
+# UefiCpuPkg Package
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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.3
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/UefiCpu
+ SUPPORTED_ARCHITECTURES = IA32|IPF|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
+
+[LibraryClasses.common.SEC]
+ PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.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
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+
+[LibraryClasses.IPF.PEIM]
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.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
+
+[Components.IA32, Components.X64]
+ UefiCpuPkg/CpuDxe/CpuDxe.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/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+ UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
+ UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+ UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+ UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+ UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+ UefiCpuPkg/SecCore/SecCore.inf
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
diff --git a/Core/UefiCpuPkg/UefiCpuPkg.uni b/Core/UefiCpuPkg/UefiCpuPkg.uni
new file mode 100644
index 0000000000..13f0e41aeb
--- /dev/null
+++ b/Core/UefiCpuPkg/UefiCpuPkg.uni
@@ -0,0 +1,149 @@
+// /** @file
+// This Package provides UEFI compatible CPU modules and libraries.
+//
+// This Package provides UEFI compatible CPU modules and libraries.
+//
+// Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are licensed and made available under
+// the terms and conditions of the BSD License which accompanies this distribution.
+// The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#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_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. If enabled, instruction executions in and data accesses to memory outside of SMRAM will be logged. This PCD is only for validation purpose. It should be set to false in production.<BR><BR>\n"
+ "TRUE - SMM Profile will be enabled.<BR>\n"
+ "FALSE - SMM Profile will be disabled.<BR>"
+
+#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.<BR><BR>\n"
+ "TRUE - the SMM profile log buffer is a ring buffer.<BR>\n"
+ "FALSE - the SMM profile log buffer is a normal buffer.<BR>"
+
+#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.<BR>\n"
+ "FALSE - SMM Startup AP in a non-blocking fashion.<BR>"
+
+#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.<BR><BR>\n"
+ "TRUE - SMM Stack Guard will be enabled.<BR>\n"
+ "FALSE - SMM Stack Guard will be disabled.<BR>"
+
+#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.<BR><BR>\n"
+ "TRUE - BSP election in SMM will be enabled.<BR>\n"
+ "FALSE - BSP election in SMM will be disabled.<BR>"
+
+#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?<BR><BR>\n"
+ "TRUE - enabled.<BR>\n"
+ "FALSE - disabled.<BR>"
+
+#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.<BR><BR>\n"
+ "TRUE - SMM Debug will be enabled.<BR>\n"
+ "FALSE - SMM Debug will be disabled.<BR>"
+
+#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?<BR><BR>\n"
+ "TRUE - locked.<BR>\n"
+ "FALSE - unlocked.<BR>"
+
+#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_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.<BR><BR>\n"
+ "TRUE - SMM Code Access Check will be enabled.<BR>\n"
+ "FALSE - SMM Code Access Check will be disabled.<BR>"
+
+#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.<BR><BR>\n"
+ "0x00 - Traditional CPU synchronization method.<BR>\n"
+ "0x01 - Relaxed CPU synchronization method.<BR>"
+
+#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."
+
diff --git a/Core/UefiCpuPkg/UefiCpuPkgExtra.uni b/Core/UefiCpuPkg/UefiCpuPkgExtra.uni
new file mode 100644
index 0000000000..858761af24
--- /dev/null
+++ b/Core/UefiCpuPkg/UefiCpuPkgExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// UefiCpu Package Localized Strings and Content.
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are licensed and made available under
+// the terms and conditions of the BSD License which accompanies this distribution.
+// The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_PACKAGE_NAME
+#language en-US
+"UefiCpu package"
+
+
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.S b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.S
new file mode 100644
index 0000000000..ede19f21c3
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#*
+#* AsmFuncs.S
+#*
+#* Abstract:
+#*
+#* Assembly function to set segment selectors.
+#
+#------------------------------------------------------------------------------
+
+.text
+
+#------------------------------------------------------------------------------
+#
+# VOID
+# EFIAPI
+# AsmSetDataSelectors (
+# IN UINT16 SelectorValue
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmSetDataSelectors)
+ASM_PFX(AsmSetDataSelectors):
+ movl 4(%esp), %eax
+ movw %ax, %ss
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ ret
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.asm b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.asm
new file mode 100644
index 0000000000..79496c48d7
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/Ia32/AsmFuncs.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; AsmFuncs.Asm
+;
+; Abstract:
+;
+; Assembly function to set segment selectors.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+.686
+.model flat,C
+
+.code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmSetDataSelectors (
+; IN UINT16 SelectorValue
+; );
+;------------------------------------------------------------------------------
+AsmSetDataSelectors PROC near public
+ mov eax, [esp + 4]
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ ret
+AsmSetDataSelectors ENDP
+
+END
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
new file mode 100644
index 0000000000..0ccf3a42b5
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
@@ -0,0 +1,1160 @@
+/** @file
+ 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,
+ control is passed to OS waking up handler.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions
+ of the BSD License which accompanies this distribution. The
+ full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ 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 <PiPei.h>
+
+#include <Guid/AcpiS3Context.h>
+#include <Guid/BootScriptExecutorVariable.h>
+#include <Guid/Performance.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/S3Resume2.h>
+#include <Ppi/SmmAccess.h>
+#include <Ppi/PostBootScriptTable.h>
+#include <Ppi/EndOfPeiPhase.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/HobLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HobLib.h>
+#include <Library/LockBoxLib.h>
+#include <IndustryStandard/Acpi.h>
+
+/**
+ 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))
+
+#pragma pack(1)
+typedef union {
+ struct {
+ UINT32 LimitLow : 16;
+ UINT32 BaseLow : 16;
+ UINT32 BaseMid : 8;
+ UINT32 Type : 4;
+ UINT32 System : 1;
+ UINT32 Dpl : 2;
+ UINT32 Present : 1;
+ UINT32 LimitHigh : 4;
+ UINT32 Software : 1;
+ UINT32 Reserved : 1;
+ UINT32 DefaultSize : 1;
+ UINT32 Granularity : 1;
+ UINT32 BaseHigh : 8;
+ } Bits;
+ UINT64 Uint64;
+} IA32_GDT;
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Reserved:1; // Reserved
+ UINT64 MustBeZero:2; // Must Be Zero
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ 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 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; //
+ UINT64 MustBeZero:8; // Must be zero;
+ UINT64 PageTableBaseAddress:31; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_ENTRY;
+
+//
+// Page Table Entry 1GB
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ 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 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; //
+ UINT64 MustBeZero:17; // Must be zero;
+ UINT64 PageTableBaseAddress:22; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_1G_ENTRY;
+
+#pragma pack()
+
+//
+// Function prototypes
+//
+/**
+ 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
+**/
+typedef
+VOID
+(EFIAPI *ASM_TRANSFER_CONTROL) (
+ IN UINT32 S3WakingVector,
+ IN UINT32 AcpiLowMemoryBase
+ );
+
+/**
+ Restores the platform to its preboot configuration for an S3 resume and
+ jumps to the OS waking vector.
+
+ This function will restore the platform to its pre-boot configuration that was
+ pre-stored in the boot script table and transfer control to OS waking vector.
+ Upon invocation, this function is responsible for locating the following
+ information before jumping to OS waking vector:
+ - ACPI tables
+ - boot script table
+ - any other information that it needs
+
+ The S3RestoreConfig() function then executes the pre-stored boot script table
+ and transitions the platform to the pre-boot state. The boot script is recorded
+ during regular boot using the EFI_S3_SAVE_STATE_PROTOCOL.Write() and
+ EFI_S3_SMM_SAVE_STATE_PROTOCOL.Write() functions. Finally, this function
+ transfers control to the OS waking vector. If the OS supports only a real-mode
+ waking vector, this function will switch from flat mode to real mode before
+ jumping to the waking vector. If all platform pre-boot configurations are
+ successfully restored and all other necessary information is ready, this
+ function will never return and instead will directly jump to the OS waking
+ vector. If this function returns, it indicates that the attempt to resume
+ from the ACPI S3 sleep state failed.
+
+ @param[in] This Pointer to this instance of the PEI_S3_RESUME_PPI
+
+ @retval EFI_ABORTED Execution of the S3 resume boot script table failed.
+ @retval EFI_NOT_FOUND Some necessary information that is used for the S3
+ resume boot path could not be located.
+
+**/
+EFI_STATUS
+EFIAPI
+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
+//
+EFI_PEI_S3_RESUME2_PPI mS3ResumePpi = { S3RestoreConfig2 };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiS3Resume2PpiGuid,
+ &mS3ResumePpi
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListPostScriptTable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiPostScriptTablePpiGuid,
+ 0
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfPeiTable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ 0
+};
+
+//
+// Global Descriptor Table (GDT)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {
+/* selector { Global Segment Descriptor } */
+/* 0x00 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+/* 0x08 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+/* 0x10 */ {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}},
+/* 0x18 */ {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}},
+/* 0x20 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+/* 0x28 */ {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 0, 1, 0}},
+/* 0x30 */ {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 0, 1, 0}},
+/* 0x38 */ {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}},
+/* 0x40 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+};
+
+#define DATA_SEGEMENT_SELECTOR 0x18
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
+ sizeof (mGdtEntries) - 1,
+ (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.
+**/
+VOID
+WriteToOsS3PerformanceData (
+ VOID
+ )
+{
+ 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;
+
+ //
+ // 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
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ 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;
+ }
+
+ 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_SIZE, 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;
+ }
+ }
+ }
+ PerfHeader->S3EntryNum = (UINT32) Index;
+}
+
+/**
+ 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.
+**/
+BOOLEAN
+IsLongModeWakingVector (
+ IN ACPI_S3_CONTEXT *AcpiS3Context
+ )
+{
+ EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+
+ 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;
+ }
+ 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->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {
+ // Both BIOS and OS wants 64bit vector
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Jump to OS waking vector.
+ The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.
+
+ @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
+ @param PeiS3ResumeState a pointer to a structure of PEI_S3_RESUME_STATE
+**/
+VOID
+EFIAPI
+S3ResumeBootOs (
+ IN ACPI_S3_CONTEXT *AcpiS3Context,
+ IN PEI_S3_RESUME_STATE *PeiS3ResumeState
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+ ASM_TRANSFER_CONTROL AsmTransferControl;
+ UINTN TempStackTop;
+ UINTN TempStack[0x10];
+
+ //
+ // Restore IDT
+ //
+ 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_END (NULL, "ScriptExec", NULL, 0);
+
+ //
+ // Install BootScriptDonePpi
+ //
+ Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get ACPI Table Address
+ //
+ 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)) ) {
+ //
+ // 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
+ //
+ Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // report status code on S3 resume
+ //
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);
+
+ PERF_CODE (
+ WriteToOsS3PerformanceData ();
+ );
+
+ AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl;
+ if (Facs->XFirmwareWakingVector != 0) {
+ //
+ // Switch to native waking vector
+ //
+ TempStackTop = (UINTN)&TempStack + 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)) {
+ //
+ // X64 long mode waking vector
+ //
+ DEBUG (( EFI_D_ERROR, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ AsmEnablePaging64 (
+ 0x38,
+ Facs->XFirmwareWakingVector,
+ 0,
+ 0,
+ (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));
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector,
+ NULL,
+ NULL,
+ (VOID *)(UINTN)TempStackTop
+ );
+ }
+ } else {
+ //
+ // 16bit Realmode waking vector
+ //
+ DEBUG (( EFI_D_ERROR, "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
+ //
+ CpuDeadLoop();
+}
+
+/**
+ 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.
+
+ @param S3NvsPageTableAddress PageTableAddress in ACPINvs
+ @param Build4GPageTableOnly If BIOS just build 4G page table only
+**/
+VOID
+RestoreS3PageTables (
+ IN UINTN S3NvsPageTableAddress,
+ IN BOOLEAN Build4GPageTableOnly
+ )
+{
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT8 PhysicalAddressBits;
+ EFI_PHYSICAL_ADDRESS PageAddress;
+ UINTN IndexOfPml4Entries;
+ UINTN IndexOfPdpEntries;
+ UINTN IndexOfPageDirectoryEntries;
+ UINT32 NumberOfPml4EntriesNeeded;
+ UINT32 NumberOfPdpEntriesNeeded;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
+ PAGE_TABLE_ENTRY *PageDirectoryEntry;
+ VOID *Hob;
+ BOOLEAN Page1GSupport;
+ PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
+
+ //
+ // 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.
+ //
+ DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));
+
+ //
+ // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.
+ //
+ PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;
+ S3NvsPageTableAddress += SIZE_4KB;
+
+ Page1GSupport = FALSE;
+ if (PcdGetBool(PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ //
+ // 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;
+ }
+ }
+
+ //
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
+ //
+ ASSERT (PhysicalAddressBits <= 52);
+ if (PhysicalAddressBits > 48) {
+ 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.
+ //
+ if (PhysicalAddressBits <= 39) {
+ NumberOfPml4EntriesNeeded = 1;
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
+ } else {
+ NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
+ NumberOfPdpEntriesNeeded = 512;
+ }
+
+ PageMapLevel4Entry = PageMap;
+ PageAddress = 0;
+ for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
+ //
+ // Each PML4 entry points to a page of Page Directory Pointer entires.
+ // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
+ //
+ PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;
+ S3NvsPageTableAddress += SIZE_4KB;
+
+ //
+ // Make a PML4 Entry
+ //
+ PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
+ 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->Bits.ReadWrite = 1;
+ PageDirectory1GEntry->Bits.Present = 1;
+ PageDirectory1GEntry->Bits.MustBe1 = 1;
+ }
+ } else {
+ for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+ //
+ // Each Directory Pointer entries points to a page of Page Directory entires.
+ // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
+ //
+ PageDirectoryEntry = (PAGE_TABLE_ENTRY *)S3NvsPageTableAddress;
+ S3NvsPageTableAddress += SIZE_4KB;
+
+ //
+ // Fill in a Page Directory Pointer Entries
+ //
+ PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
+ 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->Bits.ReadWrite = 1;
+ PageDirectoryEntry->Bits.Present = 1;
+ PageDirectoryEntry->Bits.MustBe1 = 1;
+ }
+ }
+ }
+ }
+ return ;
+ } else {
+ //
+ // If DXE is running 32-bit mode, no need to establish page table.
+ //
+ return ;
+ }
+}
+
+/**
+ Jump to boot script executor driver.
+
+ The function will close and lock SMRAM and then jump to boot script execute driver to executing S3 boot script table.
+
+ @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
+ @param EfiBootScriptExecutorVariable The function entry to executing S3 boot Script table. This function is build in
+ boot script execute driver
+**/
+VOID
+EFIAPI
+S3ResumeExecuteBootScript (
+ IN ACPI_S3_CONTEXT *AcpiS3Context,
+ IN BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable
+ )
+{
+ EFI_STATUS Status;
+ 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"));
+
+ //
+ // Attempt to use content from SMRAM first
+ //
+ GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
+ if (GuidHob != NULL) {
+ //
+ // Last step for SMM - send SMI for initialization
+ //
+
+ //
+ // Send SMI to APs
+ //
+ SendSmiIpiAllExcludingSelf ();
+ //
+ // Send SMI to BSP
+ //
+ SendSmiIpi (GetApicId ());
+
+ Status = PeiServicesLocatePpi (
+ &gPeiSmmAccessPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &SmmAccess
+ );
+ if (!EFI_ERROR (Status)) {
+ 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);
+ }
+
+ 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);
+ }
+ }
+ }
+
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ 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));
+ if (IdtBuffer == NULL) {
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
+ );
+ ASSERT (FALSE);
+ }
+ //
+ // Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer
+ // IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code
+ //
+ ZeroMem (IdtBuffer, 16);
+ AsmReadIdtr ((IA32_DESCRIPTOR *)IdtBuffer);
+ 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));
+ 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 (( EFI_D_ERROR, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState));
+ PeiS3ResumeState->ReturnCs = 0x10;
+ PeiS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs;
+ 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_START (NULL, "ScriptExec", NULL, 0);
+
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ //
+ // X64 S3 Resume
+ //
+ DEBUG (( EFI_D_ERROR, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n"));
+
+ //
+ // Switch to long mode to complete resume.
+ //
+ AsmEnablePaging64 (
+ 0x38,
+ EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,
+ (UINT64)(UINTN)AcpiS3Context,
+ (UINT64)(UINTN)PeiS3ResumeState,
+ (UINT64)(UINTN)(AcpiS3Context->BootScriptStackBase + AcpiS3Context->BootScriptStackSize)
+ );
+ } else {
+ //
+ // IA32 S3 Resume
+ //
+ DEBUG (( EFI_D_ERROR, "transfer control to Standalone Boot Script Executor\r\n"));
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT) (UINTN) EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,
+ (VOID *)AcpiS3Context,
+ (VOID *)PeiS3ResumeState,
+ (VOID *)(UINTN)(AcpiS3Context->BootScriptStackBase + AcpiS3Context->BootScriptStackSize)
+ );
+ }
+
+ //
+ // Never run to here
+ //
+ CpuDeadLoop();
+}
+/**
+ Restores the platform to its preboot configuration for an S3 resume and
+ jumps to the OS waking vector.
+
+ This function will restore the platform to its pre-boot configuration that was
+ pre-stored in the boot script table and transfer control to OS waking vector.
+ Upon invocation, this function is responsible for locating the following
+ information before jumping to OS waking vector:
+ - ACPI tables
+ - boot script table
+ - any other information that it needs
+
+ The S3RestoreConfig() function then executes the pre-stored boot script table
+ and transitions the platform to the pre-boot state. The boot script is recorded
+ during regular boot using the EFI_S3_SAVE_STATE_PROTOCOL.Write() and
+ EFI_S3_SMM_SAVE_STATE_PROTOCOL.Write() functions. Finally, this function
+ transfers control to the OS waking vector. If the OS supports only a real-mode
+ waking vector, this function will switch from flat mode to real mode before
+ jumping to the waking vector. If all platform pre-boot configurations are
+ successfully restored and all other necessary information is ready, this
+ function will never return and instead will directly jump to the OS waking
+ vector. If this function returns, it indicates that the attempt to resume
+ from the ACPI S3 sleep state failed.
+
+ @param[in] This Pointer to this instance of the PEI_S3_RESUME_PPI
+
+ @retval EFI_ABORTED Execution of the S3 resume boot script table failed.
+ @retval EFI_NOT_FOUND Some necessary information that is used for the S3
+ resume boot path could not be located.
+
+**/
+EFI_STATUS
+EFIAPI
+S3RestoreConfig2 (
+ IN EFI_PEI_S3_RESUME2_PPI *This
+ )
+{
+ EFI_STATUS Status;
+ PEI_SMM_ACCESS_PPI *SmmAccess;
+ UINTN Index;
+ ACPI_S3_CONTEXT *AcpiS3Context;
+ EFI_PHYSICAL_ADDRESS TempEfiBootScriptExecutorVariable;
+ EFI_PHYSICAL_ADDRESS TempAcpiS3Context;
+ BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;
+ UINTN VarSize;
+ EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
+ SMM_S3_RESUME_STATE *SmmS3ResumeState;
+ VOID *GuidHob;
+ BOOLEAN Build4GPageTableOnly;
+ BOOLEAN InterruptStatus;
+
+ TempAcpiS3Context = 0;
+ TempEfiBootScriptExecutorVariable = 0;
+
+ DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n"));
+
+ VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ Status = RestoreLockBox (
+ &gEfiAcpiVariableGuid,
+ &TempAcpiS3Context,
+ &VarSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = RestoreLockBox (
+ &gEfiAcpiS3ContextGuid,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context;
+ ASSERT (AcpiS3Context != NULL);
+
+ VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ Status = RestoreLockBox (
+ &gEfiBootScriptExecutorVariableGuid,
+ &TempEfiBootScriptExecutorVariable,
+ &VarSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = RestoreLockBox (
+ &gEfiBootScriptExecutorContextGuid,
+ NULL,
+ NULL
+ );
+ 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->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile));
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize));
+ DEBUG (( EFI_D_ERROR, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint));
+
+ //
+ // Additional step for BootScript integrity - we only handle BootScript and BootScriptExecutor.
+ // Script dispatch image and context (parameter) are handled by platform.
+ // 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)) {
+ // 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) {
+ 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;
+
+ SmmS3ResumeState->ReturnCs = AsmReadCs ();
+ 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)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));
+
+ if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->SmmS3ResumeEntryPoint,
+ (VOID *)AcpiS3Context,
+ 0,
+ (VOID *)(UINTN)(SmmS3ResumeState->SmmS3StackBase + SmmS3ResumeState->SmmS3StackSize)
+ );
+ }
+ if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {
+ //
+ // 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);
+
+ 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,
+ (UINT64)(UINTN)AcpiS3Context,
+ 0,
+ SmmS3ResumeState->SmmS3StackBase + SmmS3ResumeState->SmmS3StackSize
+ );
+ }
+
+ }
+
+ S3ResumeExecuteBootScript (AcpiS3Context, EfiBootScriptExecutorVariable );
+ return EFI_SUCCESS;
+}
+/**
+ 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.
+
+ @retval EFI_SUCCESS S3Resume Ppi is installed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PeimS3ResumeEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install S3 Resume Ppi
+ //
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
new file mode 100644
index 0000000000..da68e2f936
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
@@ -0,0 +1,97 @@
+## @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 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are
+# licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# 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
+ 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
+#
+
+[Sources]
+ S3Resume.c
+
+[Sources.IA32]
+ Ia32/AsmFuncs.asm
+ Ia32/AsmFuncs.S | GCC
+
+[Sources.X64]
+ X64/AsmFuncs.asm
+ X64/AsmFuncs.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ PeiServicesTablePointerLib
+ PerformanceLib
+ HobLib
+ PeiServicesLib
+ PeimEntryPoint
+ TimerLib
+ BaseLib
+ DebugLib
+ PcdLib
+ IoLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ DebugAgentLib
+ LocalApicLib
+ ReportStatusCodeLib
+ LockBoxLib
+ PrintLib
+
+[Guids]
+ gEfiBootScriptExecutorVariableGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox
+ gEfiBootScriptExecutorContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox
+ gPerformanceProtocolGuid ## SOMETIMES_CONSUMES ## Variable:L"PerfDataMemAddr"
+ ## SOMETIMES_CONSUMES ## HOB
+ ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox
+ gEfiAcpiVariableGuid
+ gEfiAcpiS3ContextGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gEfiPeiS3Resume2PpiGuid ## PRODUCES
+ gPeiSmmAccessPpiGuid ## SOMETIMES_CONSUMES
+ gPeiPostScriptTablePpiGuid ## SOMETIMES_PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ S3Resume2PeiExtra.uni
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni
new file mode 100644
index 0000000000..0f78a15173
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.uni
@@ -0,0 +1,26 @@
+// /** @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 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are
+// licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#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/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni
new file mode 100644
index 0000000000..4d88423149
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2PeiExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// S3Resume2Pei Localized Strings and Content
+//
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are
+// licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"S3 Resume v2 PEI Module"
+
+
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.S b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.S
new file mode 100644
index 0000000000..2ced09f35c
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.S
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------
+#*
+#* Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+#* This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#*
+#* AsmFuncs.S
+#*
+#* Abstract:
+#*
+#* Assembly function to set segment selectors.
+#
+#------------------------------------------------------------------------------
+
+.text
+
+#------------------------------------------------------------------------------
+#
+# VOID
+# EFIAPI
+# AsmSetDataSelectors (
+# IN UINT16 SelectorValue
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmSetDataSelectors)
+ASM_PFX(AsmSetDataSelectors):
+ movw %cx, %ss
+ movw %cx, %ds
+ movw %cx, %es
+ movw %cx, %fs
+ movw %cx, %gs
+ ret
diff --git a/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.asm b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.asm
new file mode 100644
index 0000000000..eb014a5862
--- /dev/null
+++ b/Core/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/X64/AsmFuncs.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; 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:
+;
+; AsmFuncs.Asm
+;
+; Abstract:
+;
+; Assembly function to set segment selectors.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+.code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmSetDataSelectors (
+; IN UINT16 SelectorValue
+; );
+;------------------------------------------------------------------------------
+AsmSetDataSelectors PROC
+ mov ds, cx
+ mov es, cx
+ mov fs, cx
+ mov gs, cx
+ mov ss, cx
+ ret
+AsmSetDataSelectors ENDP
+
+END