summaryrefslogtreecommitdiff
path: root/Core/CPU
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/CPU
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/CPU')
-rw-r--r--Core/CPU/CPU.h443
-rw-r--r--Core/CPU/CPUCore.cif30
-rw-r--r--Core/CPU/CPUCspLib.h333
-rw-r--r--Core/CPU/CpuCspLib.c2461
-rw-r--r--Core/CPU/CpuDxe.c2096
-rw-r--r--Core/CPU/CpuDxe.dxs57
-rw-r--r--Core/CPU/CpuDxe.h158
-rw-r--r--Core/CPU/CpuDxeFuncs.c1101
-rw-r--r--Core/CPU/CpuPei.c936
-rw-r--r--Core/CPU/CpuPei.dxs65
-rw-r--r--Core/CPU/CpuPei.h206
-rw-r--r--Core/CPU/CpuPeiBeforeMem.c1268
-rw-r--r--Core/CPU/CpuPeiFuncs.c1378
-rw-r--r--Core/CPU/CpuSmbios.c734
-rw-r--r--Core/CPU/CpuSpSmi.DXS59
-rw-r--r--Core/CPU/CpuSpSmi.c568
-rw-r--r--Core/CPU/CpuSpSmi.cif12
-rw-r--r--Core/CPU/CpuSpSmi.h118
-rw-r--r--Core/CPU/CpuSpSmi.mak65
-rw-r--r--Core/CPU/CpuSpSmi.sdl56
-rw-r--r--Core/CPU/CpuTools.cif10
-rw-r--r--Core/CPU/CpuTools.sdl13
-rw-r--r--Core/CPU/CreateSecFfs.exebin0 -> 45056 bytes
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.cif12
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.mak67
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.sdl19
-rw-r--r--Core/CPU/IA32/FoundationIa32.cif16
-rw-r--r--Core/CPU/IA32/FoundationIa32.mak69
-rw-r--r--Core/CPU/IA32/FoundationIa32.sdl19
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm143
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm78
-rw-r--r--Core/CPU/IA32/IA32CLib.c1959
-rw-r--r--Core/CPU/IA32/IA32Core.cif9
-rw-r--r--Core/CPU/IA32/IA32Core.sdl33
-rw-r--r--Core/CPU/IA32/IA32rules.mak62
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.c93
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.h85
-rw-r--r--Core/CPU/IA32/Processor.c140
-rw-r--r--Core/CPU/IA32/Processor.h27
-rw-r--r--Core/CPU/IA32/ProcessorAsms.Asm223
-rw-r--r--Core/CPU/IA32/SwitchCoreStacks.asm104
-rw-r--r--Core/CPU/IA32/efijump.h34
-rw-r--r--Core/CPU/IPF/FoundationIPF.cif24
-rw-r--r--Core/CPU/IPF/FoundationIPF.mak66
-rw-r--r--Core/CPU/IPF/FoundationIPF.sdl19
-rw-r--r--Core/CPU/IPF/IpfCpuCore.i93
-rw-r--r--Core/CPU/IPF/IpfCpuCore.s196
-rw-r--r--Core/CPU/IPF/PeCoffLoaderEx.c268
-rw-r--r--Core/CPU/IPF/PeCoffLoaderEx.h87
-rw-r--r--Core/CPU/IPF/PerformancePrimitives.s61
-rw-r--r--Core/CPU/IPF/Processor.h27
-rw-r--r--Core/CPU/IPF/SwitchStack.s122
-rw-r--r--Core/CPU/IPF/SwitchToCacheMode.c77
-rw-r--r--Core/CPU/IPF/asm.h35
-rw-r--r--Core/CPU/IPF/efijump.h112
-rw-r--r--Core/CPU/IPF/ia_64gen.h214
-rw-r--r--Core/CPU/IPF/pioflush.s106
-rw-r--r--Core/CPU/IPF/processor.c118
-rw-r--r--Core/CPU/IPF/setjmp.s325
-rw-r--r--Core/CPU/MBIOSMAC.MAC512
-rw-r--r--Core/CPU/MicrocodeUpdate/FwhFvb.c140
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c1164
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif13
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs48
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h133
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak58
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl32
-rw-r--r--Core/CPU/ResetVector.asm99
-rw-r--r--Core/CPU/SecFixup.exebin0 -> 45056 bytes
-rw-r--r--Core/CPU/Startup32.asm618
-rw-r--r--Core/CPU/x64/AmiX64Lib.cif52
-rw-r--r--Core/CPU/x64/AmiX64Lib.mak63
-rw-r--r--Core/CPU/x64/AmiX64Lib.sdl19
-rw-r--r--Core/CPU/x64/EfiJump.h42
-rw-r--r--Core/CPU/x64/Foundationx64.cif15
-rw-r--r--Core/CPU/x64/Foundationx64.mak65
-rw-r--r--Core/CPU/x64/Foundationx64.sdl19
-rw-r--r--Core/CPU/x64/MiscLib/Misc.asm124
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.cif10
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.mak74
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.sdl19
-rw-r--r--Core/CPU/x64/PeCoffLoaderEx.c87
-rw-r--r--Core/CPU/x64/PeCoffLoaderEx.h85
-rw-r--r--Core/CPU/x64/Processor.c146
-rw-r--r--Core/CPU/x64/Processor.h27
-rw-r--r--Core/CPU/x64/ProcessorAsms.Asm186
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm80
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm130
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_Pause.asm80
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/GetCpuTimer.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/GetCsSegment.asm79
-rw-r--r--Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/HltCpu.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead16.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead32.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead64.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead8.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite16.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite32.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite64.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite8.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/MemCpy.asm178
-rw-r--r--Core/CPU/x64/x64AsmLib/MemCpy32.asm178
-rw-r--r--Core/CPU/x64/x64AsmLib/MemRead32.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/MemReadWrite32.asm93
-rw-r--r--Core/CPU/x64/x64AsmLib/MemSet.asm127
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadCr3.asm79
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadMsr.asm85
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadRtdsc.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm88
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitForever.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm86
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm86
-rw-r--r--Core/CPU/x64/x64AsmLib/WriteCr3.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/WriteMsr.asm89
-rw-r--r--Core/CPU/x64/x64AsmLib/checkpoint.asm84
-rw-r--r--Core/CPU/x64/x64CLib.c328
-rw-r--r--Core/CPU/x64/x64Core.cif9
-rw-r--r--Core/CPU/x64/x64Core.sdl112
-rw-r--r--Core/CPU/x64/x64rules.mak86
132 files changed, 25486 insertions, 0 deletions
diff --git a/Core/CPU/CPU.h b/Core/CPU/CPU.h
new file mode 100644
index 0000000..8795524
--- /dev/null
+++ b/Core/CPU/CPU.h
@@ -0,0 +1,443 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPU.h 3 10/17/12 2:20a Davidhsieh $
+//
+// $Revision: 3 $
+//
+//
+// $Date: 10/17/12 2:20a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPU.h $
+//
+// 3 10/17/12 2:20a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Setup items CTDP BIOS, C8, C9 and C10 created
+//
+// 2 9/26/12 10:53a Davidhsieh
+// [TAG] None
+// [Description] Add CPU APIC ID data variable for S3 resume
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: Cpu.h
+//
+// Description: Common header for the CPU.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_H__
+#define __CPU_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <efi.h>
+
+#ifdef PEI_COMPILE //In PEI, this must be defined before including this file.
+#include <pei.h>
+#include <Ppi/Stall.h>
+#endif
+
+#define MP_CPU_APIC_ID_DATA_GUID \
+ {0x1456cc6e, 0x22ac, 0x5289, 0x33, 0xba, 0x2e, 0x13, 0xbb, 0xda, 0xba, 0xee}
+
+// Define the equates here
+//CPU APIC includes
+#define APIC_ALL_EXCLUDING_SELF (3 << 18)
+#define APIC_SIPI (6 << 8)
+#define APIC_INIT (5 << 8)
+#define APIC_SMI (2 << 8)
+#define APIC_DELIVERY_STATUS (1 << 12)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_LEVEL_DEASSERT (0 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+
+#define MSR_XAPIC_BASE 0x1B
+#define XAPIC_BASE_BSP_BIT 8
+#define XAPIC_X2APIC_ENABLE_BIT 10
+#define XAPIC_GLOBAL_ENABLE_BIT 11
+
+
+#define XAPIC_ENABLE_BIT 8 // SVR SW APIC Enable/Disable Bit
+#define APIC_PRESENT_BIT 9 // APIC Present bit in Feature Flags
+
+#define MASK_ICR_CLEAR 0xFFF33000 // AND mask for ICR reserved bit
+#define OR_MASK_INIT_IPI 0x00004500 // OR mask to send INIT IPI
+#define OR_MASK_USE_DEST_FIELD 0x00000000 // OR mask to set dest field = "Dest Field"
+
+//Cstate
+#define C1_SUB_STATES_MASK 0x000000f0
+#define C3_SUB_STATES_MASK 0x00000f00
+#define C6_SUB_STATES_MASK 0x0000f000
+#define C7_SUB_STATES_MASK 0x000f0000
+#define C8_SUB_STATES_MASK 0x00f00000
+#define C9_SUB_STATES_MASK 0x0f000000
+#define C10_SUB_STATES_MASK 0xf0000000
+
+//-----------------------------------------------------------------------------
+// Local APIC Register Equates
+//-----------------------------------------------------------------------------
+#define LOCAL_APIC_ID 0x20
+#define LOCAL_APIC_VERSION 0x30
+#define LOCAL_APIC_TASK_PRI 0x80
+#define LOCAL_APIC_ARB_PRI 0x90
+#define LOCAL_APIC_PROC_PRI 0xa0
+#define LOCAL_APIC_EOI 0xb0
+#define LOCAL_APIC_LDR 0xd0
+#define LOCAL_APIC_DEST_FORMAT 0xe0
+#define LOCAL_APIC_SVR 0xf0
+#define LOCAL_APIC_ISR0 0x100
+#define LOCAL_APIC_TMR0 0x180
+#define LOCAL_APIC_IRR0 0x200
+#define LOCAL_APIC_ERR_STAT 0x280
+#define LOCAL_APIC_ICR_LO 0x300
+#define LOCAL_APIC_ICR_HI 0x310
+#define LOCAL_APIC_LVT 0x320
+#define LOCAL_APIC_PERF 0x340
+#define LOCAL_APIC_LVT_LINT0 0x350
+#define LOCAL_APIC_LVT_LINT1 0x360
+#define LOCAL_APIC_LVT_ERR 0x370
+#define LOCAL_APIC_ITC 0x380
+#define LOCAL_APIC_TIMER 0x390
+#define LOCAL_APIC_TMR_DIV 0x3e0
+
+#define PSD_SW_ALL 0xfc
+#define PSD_SW_ANY 0xfd
+#define PSD_HW_ALL 0xfe
+
+#define TSD_HW_ALL 0xfe
+
+#define MSR_IA32_PLATFORM_ID 0x17
+#define MSR_CHL_CONTROLS 0x2d
+ #define B_FORWARD_CODE_DISABLE (1<<9)
+#define MSR_IA32_CR_PIC_MSG_CONTROL 0x2e
+#define MSR_CORE_THREAD_COUNT 0x35
+#define MSR_IA32_FEATURE_CONTROL 0x3a
+ #define SMRR_LOCK_BIT 0x1
+ #define SMRR_ENABLE_BIT 0x3
+ #define SMRR_ENABLE_MASK (1<<3)
+#define MSR_SMM_SAVE_CONTROL 0x3e
+#define MSR_IA32_BIOS_UPDT_TRIG 0x79
+#define MSR_IA32_BIOS_SIGN_ID 0x8b
+#define MSR_PMG_CST_CONFIG_CONTROL 0xe2
+#define MSR_PMG_IO_CAPTURE_ADDR 0xe4
+#define MSR_PLATFORM_INFO 0xce
+ #define TCC_ACTIVE_OFFSET_PROGRAMMABLE_BIT 30
+ #define XE_TDP_TDC_PROGRAMMABLE_BIT 29
+ #define XE_CORE_RATIO_PROGRAMMABLE_BIT 28
+ #define SMM_SAVE_CONTROL_BIT 16
+ #define MAX_NON_TURBO_RATIO_OFFSET 8
+ #define MAX_NON_TURBO_RATIO_MASK 0xff
+#define MSR_FEATURE_CONFIG 0x13c
+ #define MSR_FEATURE_CONFIG_LOCK 1
+#define MSR_IA32_MCG_CAP 0x179
+#define MSR_IA32_MCG_CTL 0x17b
+#define MSR_FLEX_RATIO 0x194
+#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_IA32_PERF_CTL 0x199
+#define MSR_IA32_CLOCK_MODULATION 0x19a
+ #define CLK_MOD_ENABLE 0x10
+#define MSR_IA32_MISC_ENABLE 0x1a0
+ #define TURBO_DISABLE_MASK ((UINT64)1 << 38)
+ #define TURBO_MODE_DISABLE_BIT 38
+#define MSR_MISC_FEATURE_CONTROL 0x1a4
+ #define DATA_REUSE_OPT 0x40
+ #define DCU_IP_PREFETCHER 0x8
+ #define DCU_STREAMER_PREFETCHER 0x4
+ #define MLC_SPATIAL_PREFETCHER 0x2
+ #define MLC_STREAMER_PREFETCHER 0x1
+#define MSR_MISC_PWR_MGMT 0x1aa
+ #define EIST_HW_COORD_DIS_BIT 0
+ #define ENG_PERF_BIAS_EN_BIT 1
+ #define LOCK_TM_INT_BIT 22
+#define MSR_TURBO_POWER_CURRENT_LIMIT 0x1ac
+ #define TDC_LIMIT_OVERRIDE_ENABLE_BIT 31
+ #define TDC_LIMIT_MASK 0x7FFF0000
+ #define TDC_LIMIT_OFFSET 16
+ #define TDP_LIMIT_OVERRIDE_ENABLE_BIT 15
+ #define TDP_LIMIT_MASK 0x7FFF
+ #define TDP_LIMIT_OFFSET 0
+#define MSR_TURBO_RATIO_LIMIT 0x1ad
+ #define MAX_RATIO_LIMIT_8C_OFFSET 56
+ #define MAX_RATIO_LIMIT_7C_OFFSET 48
+ #define MAX_RATIO_LIMIT_6C_OFFSET 40
+ #define MAX_RATIO_LIMIT_5C_OFFSET 32
+ #define MAX_RATIO_LIMIT_4C_OFFSET 24
+ #define MAX_RATIO_LIMIT_3C_OFFSET 16
+ #define MAX_RATIO_LIMIT_2C_OFFSET 8
+ #define MAX_RATIO_LIMIT_1C_OFFSET 0
+ #define MAX_RATIO_LIMIT_MASK 0xff
+#define MSR_IA32_ENERGY_PERF_BIAS 0x1b0
+#define MSR_FERR_CAPABILITY 0x1f1
+#define MSR_EMRR_PHYSBASE 0x1f4
+#define MSR_EMRR_PHYSMASK 0x1f5
+#define B_EMRR_VALID (1 << 11)
+#define MSR_IA32_PLATFORM_DCA_CAP 0x1f8
+#define MSR_IA32_DCA_CAP 0x1f9
+#define MSR_IA32_DCA_0_CAP 0x1fa
+#define MSR_POWER_CTL 0x1fc
+#define MSR_IA32_MC0_CTL 0x400
+#define MSR_IA32_MC0_STATUS 0x401
+
+// Generic MTRR equates
+#define MTRR_ATTRIB_WB 6
+
+#define MSR_IA32_MTRR_CAP 0xfe
+ #define SMRR_SUPPORT_BIT 11
+ #define SMRR_SUPPORT_MASK (1 << 11)
+ #define EMRR_SUPPORT_MASK (1 << 12)
+#define MTRR_PHYS_BASE_0 0x200
+#define MTRR_PHYS_MASK_0 0x201
+#define MTRR_PHYS_BASE_1 0x202
+#define MTRR_PHYS_MASK_1 0x203
+#define MTRR_PHYS_BASE_2 0x204
+#define MTRR_PHYS_MASK_2 0x205
+#define MTRR_PHYS_BASE_3 0x206
+#define MTRR_PHYS_MASK_3 0x207
+#define MTRR_PHYS_BASE_4 0x208
+#define MTRR_PHYS_MASK_4 0x209
+#define MTRR_PHYS_BASE_5 0x20a
+#define MTRR_PHYS_MASK_5 0x20b
+#define MTRR_PHYS_BASE_6 0x20c
+#define MTRR_PHYS_MASK_6 0x20d
+#define MTRR_PHYS_BASE_7 0x20e
+#define MTRR_PHYS_MASK_7 0x20f
+#define MTRR_FIX_64K_00000 0x250
+#define MTRR_FIX_16K_80000 0x258
+#define MTRR_FIX_16K_A0000 0x259
+#define MTRR_FIX_4K_C0000 0x268
+#define MTRR_FIX_4K_C8000 0x269
+#define MTRR_FIX_4K_D0000 0x26a
+#define MTRR_FIX_4K_D8000 0x26b
+#define MTRR_FIX_4K_E0000 0x26c
+#define MTRR_FIX_4K_E8000 0x26d
+#define MTRR_FIX_4K_F0000 0x26e
+#define MTRR_FIX_4K_F8000 0x26f
+#define MSR_IA32_MC8_CTL2 0x288
+#define MTRR_DEF_TYPE 0x2ff
+#define MSR_NO_EVICT_MODE 0x2e0
+#define B_MSR_NO_EVICT_MODE_SETUP 1
+#define B_MSR_NO_EVICT_MODE_RUN 2
+#define MSR_UNCORE_CR_MEMLOCK_COMMANDS 0x2e2
+
+#define MSR_PP0_CURRENT_CONFIG 0x601
+#define MSR_PP1_CURRENT_CONFIG 0x602
+#define MSR_PACKAGE_POWER_SKU_LIMIT 0x606
+#define MSR_PKGC3_IRTL 0x60a
+#define MSR_PKGC6_IRTL 0x60b
+#define MSR_PKGC7_IRTL 0x60c
+#define MSR_TURBO_POWER_LIMIT 0x610
+ #define POWER_LIMIT_1_MASK 0x7fff
+ #define POWER_LIMIT_1_TIME_MASK 0xfe0000
+ #define POWER_LIMIT_2_MASK (UINT64)0x7fff00000000
+#define MSR_PACKAGE_POWER_SKU 0x614
+#define MSR_PP0_POWER_LIMIT 0x638
+#define MSR_PP1_POWER_LIMIT 0x640
+
+#define MSR_EXT_XAPIC_LOGICAL_APIC_ID 0x802
+#define MSR_EXT_XAPIC_VERSION 0x803
+#define MSR_EXT_XAPIC_SVR 0x80f
+#define B_MSR_XAPIC_SVR_SOFTWARE_ENABLE (1 << 8)
+#define MSR_EXT_XAPIC_ICR 0x830
+#define MSR_EXT_XAPIC_LVT_LINT0 0x835
+#define MSR_EXT_XAPIC_LVT_LINT1 0x836
+
+#define GAINESTOWN 0x106a0
+#define WESTMERE 0x206c0
+#define NEHALEM_EX 0x206e0
+#define WESTMERE_EX 0x206f0
+#define SANDY_BRIDGE 0x206a0
+#define JAKETOWN 0x206d0
+#define IVY_BRIDGE 0x306a0
+
+#define NUM_OF_FIXED_MTRRS 11
+
+VOID LockInc32(UINT32 *);
+
+typedef struct {
+ UINT32 SmrrSupport:1;
+ UINT32 DcaSupport:1;
+ UINT32 Rsv1:30;
+ UINT32 Rsv2:32;
+} BOARD_ADDITIONAL_FEATURE_FLAGS;
+
+typedef struct {
+ UINT32 FeatureEcx;
+ UINT32 FeatureEdx;
+ UINT32 ExtFeatureEax;
+ UINT32 ExtFeatureEbx;
+ UINT32 ExtFeatureEcx;
+ UINT32 ExtFeatureEdx;
+ BOARD_ADDITIONAL_FEATURE_FLAGS Flags;
+} BOARD_CPU_FEATURES;
+
+UINT32 GetMinCpuFeatures(
+ IN UINT8 NumCpus,
+ IN VOID *MpData,
+ IN BOARD_CPU_FEATURES *AllFeatures,
+ OUT BOARD_CPU_FEATURES *Feature
+);
+
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINTN Base; //This shared between 32 bit and 64 bit.
+} DESCRIPTOR_TABLE;
+
+typedef struct _MP_CPU_APICID_DATA {
+ UINT8 NumberOfCpu;
+ UINT8 ApicId[32];
+} MP_CPU_APICID_DATA;
+#pragma pack()
+
+#define MP_AP_ONLY 0
+#define MP_BSP_AP 1
+
+#define MP_PARALLEL 0
+#define MP_SERIALIZE 1
+
+#define MP_FREERUN 0
+#define MP_WAIT 1
+UINT32 StartCpus(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *ApGlobalData OPTIONAL,
+ IN BOOLEAN AllCpus,
+ IN UINT32 ApicId, //If only 1 cpu
+ IN VOID *Address
+);
+
+VOID StartAllAps(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ OUT VOID **MpData
+);
+VOID PrepareApsForNormalExec(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+#endif
+ IN VOID *MpData
+);
+VOID EarlyExecuteFunctionOnRunningCpus(
+ IN VOID *MpData,
+ IN VOID (*Function)(UINT32, VOID *Context), //First parameters will always be 0.
+ IN VOID *Context
+);
+VOID RestartAp(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+VOID SetHaltFunction(
+ IN VOID *MpData,
+ IN VOID *Function
+);
+
+UINT32 GetNumCpus(VOID *MpData);
+VOID ExecuteFunctionOnRunningCpus(
+ IN VOID *MpData,
+ IN BOOLEAN ExecuteOnBsp,
+ IN BOOLEAN Serialize,
+ IN BOOLEAN Block,
+ IN VOID (*Function)(UINT32 Cpu, VOID *Context),
+ IN VOID *Context
+);
+BOOLEAN ExecuteFunctionOnCpu(
+ IN VOID *MpData,
+ IN UINT32 Cpu,
+ IN BOOLEAN Block,
+ IN VOID (*Function)(UINT32 Cpu, VOID *Context),
+ IN VOID *Context
+);
+VOID HaltAllAps(
+ IN VOID *MpData,
+ IN BOOLEAN WaitUntilHalted
+);
+VOID HaltCpu(
+ IN VOID *MpData,
+ IN UINT32 Cpu,
+ IN BOOLEAN WaitUntilHalted
+);
+BOOLEAN IsCpuHalted(
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+BOOLEAN IsCpuIdle(
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+BOOLEAN AreCpusIdle(
+ IN VOID *MpData
+);
+
+UINT32 WhoIsBsp(VOID *MpData);
+
+UINT32 GetCpuBist(IN VOID *MpData, IN UINT32 Cpu);
+UINT32 GetCpuNumByApicId(VOID *MpData, UINT32 ApicId);
+
+VOID SwitchBsp(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *MpData,
+ IN UINT32 NewBsp
+);
+
+VOID ProgramLocalApic(IN UINT32 Cpu, IN VOID *Context);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CPUCore.cif b/Core/CPU/CPUCore.cif
new file mode 100644
index 0000000..6e1b63d
--- /dev/null
+++ b/Core/CPU/CPUCore.cif
@@ -0,0 +1,30 @@
+<component>
+ name = "CPU Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU"
+ RefName = "CPU Core"
+[files]
+"CPU.h"
+"CpuCspLib.c"
+"CPUCspLib.h"
+"CpuDxe.c"
+"CpuDxe.dxs"
+"CpuDxe.h"
+"CpuPei.c"
+"CpuPei.dxs"
+"CpuPei.h"
+"CpuPeiFuncs.c"
+"CpuDxeFuncs.c"
+"CpuPeiBeforeMem.c"
+"CpuSmbios.c"
+"MBIOSMAC.MAC"
+"ResetVector.asm"
+"Startup32.asm"
+[parts]
+"CPU Hobs"
+"CpuPPIs"
+"CpuProtocols"
+"MicrocodeUpdate"
+"CpuTools"
+"MiscX64Lib"
+<endComponent>
diff --git a/Core/CPU/CPUCspLib.h b/Core/CPU/CPUCspLib.h
new file mode 100644
index 0000000..94f282a
--- /dev/null
+++ b/Core/CPU/CPUCspLib.h
@@ -0,0 +1,333 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPUCspLib.h 5 2/07/13 3:57a Hsingyingchung $
+//
+// $Revision: 5 $
+//
+// $Date: 2/07/13 3:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPUCspLib.h $
+//
+// 5 2/07/13 3:57a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+//
+// 4 12/20/12 10:27a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 3 11/23/12 2:08a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 2 5/17/12 9:40p Davidhsieh
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuCspLib.h
+//
+// Description: Header file for Cpu Csp Lib.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPULIB_H__
+#define __CPULIB_H__
+
+#include <efi.h>
+#include <pei.h>
+#include "amihobs.h"
+#include "smm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Bist;
+} AMI_STATUS_CODE_CPU_BIST_DATA;
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 HeaderVersion;
+ UINT32 UpdateRevision;
+ UINT32 Date;
+ UINT32 CpuSignature;
+ UINT32 Checksum;
+ UINT32 LoaderRevison;
+ UINT32 Flags:8;
+ UINT32 RV3:24;
+ UINT32 DataSize;
+ UINT32 TotalSize;
+ UINT32 RV4[3];
+} MICROCODE_HEADER;
+
+typedef struct {
+ UINT32 CpuSignature;
+ UINT32 Flags;
+ UINT32 Checksum;
+} PROC_SIG;
+
+typedef struct {
+ UINT32 Count;
+ UINT32 Checksum;
+ UINT8 Rsv[12];
+ PROC_SIG ProcSig[1];
+} MICROCODE_EXT_PROC_SIG_TABLE;
+
+#pragma pack(pop)
+
+// {CD541D77-6699-4b36-A31E-1AA4C5D5B946}
+#define AMI_STATUS_CODE_CPU_BIST_DATA_GUID \
+ {0xcd541d77, 0x6699, 0x4b36, 0xa3, 0x1e, 0x1a, 0xa4, 0xc5, 0xd5, 0xb9, 0x46}
+
+UINT64 ReadMsr (UINT32 Msr);
+VOID WriteMsr(UINT32 Msr, UINT64 Value);
+VOID ReadWriteMsr(UINT32 Msr, UINT64 Value, UINT64 Mask);
+VOID CPULib_CpuID(UINT32 CpuIDIndex, UINT32 * RegEAX, UINT32 * RegEBX,
+ UINT32 * RegECX, UINT32 * RegEDX);
+UINT32 GetCpuSignature();
+UINT32 GetCpuFamily(UINT32 CpuSignature);
+UINT32 GetCpuModel(UINT32 CpuSignature);
+UINT32 GetCpuPlatformId();
+UINT32 GetSmrrBaseMsr();
+UINT8 NumSupportedThreadsPerCore();
+UINT8 NumSupportedCpuCores();
+UINT8 NumCpuCores();
+UINT8 NumLogicalCpus();
+BOOLEAN IsHtEnabled();
+BOOLEAN IsHt0();
+BOOLEAN IsCore0();
+BOOLEAN isXDSupported(CPU_FEATURES *Features);
+BOOLEAN isTurboModeSupported();
+BOOLEAN isFullUnlockCpuSuuported();
+BOOLEAN isXETdcTdpLimitSupported();
+BOOLEAN isXECoreRatioLimitSupported();
+BOOLEAN isLimitCpuidSupported();
+BOOLEAN IsMachineCheckSupported(CPU_FEATURES *Features);
+BOOLEAN IsEnergyPerfBiasSupported();
+BOOLEAN IsCxInterruptFilteringSupported();
+BOOLEAN IsVmxSupported(CPU_FEATURES *Features);
+BOOLEAN IsSmxSupported(CPU_FEATURES *Features);
+BOOLEAN IsSmrrSupported(CPU_FEATURES *Features);
+BOOLEAN IsX64Supported(CPU_FEATURES *Features);
+
+BOOLEAN CPULib_IsVmxEnabled();
+BOOLEAN CPULib_IsSmxEnabled();
+BOOLEAN CPULib_IsSmrrEnabled();
+BOOLEAN CPULib_IsLocalX2ApicEnabled();
+BOOLEAN CPULib_IsFeatureControlLocked();
+UINT32 NumberOfCpuSocketsPopulated();
+VOID DisableCacheInCR0();
+VOID EnableCacheInCR0();
+VOID CPULib_DisableInterrupt();
+VOID CPULib_EnableInterrupt();
+BOOLEAN CPULib_GetInterruptState();
+VOID* CPULIB_GetPageTable();
+VOID CPULib_Pause();
+UINT16 GetCsSegment();
+UINT64 ReadRtdsc();
+VOID WaitForever();
+VOID HltCpu();
+VOID WaitForSemaphore(volatile VOID*);
+VOID WaitUntilZero8(volatile VOID*);
+VOID WaitUntilZero32(volatile VOID*);
+UINT16 GetCsSegment();
+UINT32 CPULIB_GetCstateLatency(IN UINT8 Cstate);
+UINT32 CPULIB_GetCstatePower(IN UINT8 Cstate);
+VOID* CPULib_FindMicrocode();
+UINT32 CPULib_GetMicrocodeVer();
+VOID ClearDirectionFlag();
+
+UINT32 SmmGetBaseSaveBufferSize();
+VOID SmmSetupDefaultHandler(IN VOID *SmmBaseSaveBuffer, IN SMM_HOB *SmmHob);
+VOID SmmRemoveDefaultHandler(IN VOID *SmmBaseSaveBuffer);
+VOID SmmBaseChangeOnCpu(VOID *SmmBase);
+
+VOID CPU_GetSaveState (
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState);
+
+VOID CPU_RestoreSaveState(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState);
+
+VOID CPU_SmmMemoryInit(IN SMM_HOB *SmmHob);
+
+typedef struct {
+ UINT8 ClkModEn; //> 0 if Clk Mod En.
+} CPU_LIB_SMM_SAVE_RESTORE_DATA;
+
+VOID CpuLib_SmmSaveCpuState(IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA*);
+VOID CpuLib_SmmRestoreCpuState(IN CPU_LIB_SMM_SAVE_RESTORE_DATA*);
+
+BOOLEAN IsSwSmiTrigger(UINT8 *SmmBase, UINT16 SwSmiPort);
+
+EFI_STATUS CPULib_SmmReadSaveState(
+ UINT8 *SmmBase,
+ UINT8 *SstSaveState,
+ BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+EFI_STATUS CpuLib_SmmReadSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+EFI_STATUS CPULib_SmmWriteSaveState(
+ UINT8 *SmmBase,
+ UINT8 *SstSaveState,
+ BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT CONST VOID *Buffer
+);
+EFI_STATUS CpuLib_SmmWriteSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS CPUProgramPAMRegisters(
+ EFI_BOOT_SERVICES *gBS, EFI_RUNTIME_SERVICES *gRS,
+ UINT32 StartAddress, UINT32 Length, UINT8 Setting, UINT32 *Granularity
+);
+
+VOID EnableMachineCheck();
+
+VOID CPULib_LockByteInc(UINT8* ptr);
+VOID CPULib_LockByteDec(UINT8* ptr);
+VOID CPULib_LoadGdt(VOID *ptr);
+VOID CPULib_SaveGdt(VOID *ptr);
+VOID CPULib_LoadIdt(VOID *ptr);
+VOID CPULib_SaveIdt(VOID *ptr);
+
+UINT32 MemRead32(UINT32 *Address);
+VOID MemReadWrite32(UINT32 *Address, UINT32 Value, UINT32 Mask);
+
+UINT8 IsPowerCycle();
+BOOLEAN isBCLKRatioSuuported();
+EFI_STATUS GetOcCapability(IN UINT8 DomainID, OUT UINT64 *MsrBuf);
+EFI_STATUS GetSVIDConfig(OUT UINT64 *MsrBuf);
+EFI_STATUS GetVoltFreq(IN UINT8 DomainID, OUT UINT64 *MsrBuf);
+EFI_STATUS GetFIVRConfig(OUT UINT64 *MsrBuf);
+
+
+#ifdef PERF_TUNE_SUPPORT
+#if PERF_TUNE_SUPPORT == 1
+
+#define AMI_OVERCLOCK_CONFIG_HOB_GUID \
+ {0x27a29ef7, 0x90e7, 0x4592, 0x99, 0xbe, 0xa3, 0xae, 0x97, 0xca, 0xdb, 0x2a}
+
+#define AMI_INTERNAL_CPU_RATIO_LIMIT \
+ {0xdf2982fa, 0xaa6c, 0x4b8d, 0x8a, 0x82, 0x85, 0xf8, 0x1e, 0xe8, 0x72, 0x19}
+
+#pragma pack(1)
+//Domain ID define
+#define DOMAIN_MAX_NUM 6
+#define IA 0
+#define GT 1
+#define RING 2
+#define SA 3
+#define IOD 4
+#define IOA 5
+
+typedef struct {
+ UINT8 MaxOcRatioLimit;
+ BOOLEAN RatioOcSupported;
+ BOOLEAN VoltageOverridesSupported;
+ BOOLEAN VoltageOffsetSupported;
+} OC_CAP_ITEM; //overclocking capability
+
+typedef struct {
+ UINT8 MaxOcRatio;
+ BOOLEAN VoltageTargetMode; // 0: Adaptive, 1: Override
+ UINT16 VoltageTarget;
+ INT16 VoltageOffset;
+} VOLT_FREQ_DEF_ITEM;
+
+typedef struct {
+ OC_CAP_ITEM OCCap[DOMAIN_MAX_NUM];
+ VOLT_FREQ_DEF_ITEM VFDef[DOMAIN_MAX_NUM];
+ BOOLEAN SvidDisable; // 0: Disable, 1: Enable
+ UINT16 SvidVoltageOverride; // External VR voltage override
+ BOOLEAN FivrFaultsDisable; // 0: Disable, 1: Enable
+ BOOLEAN FivrEfficiencyDisable; // 0: Disable, 1: Enable
+ BOOLEAN OcSupport;
+ UINT8 IsPowerCycle; // 0: Not power cycle, 1: power cycle
+ UINT8 IsCpuRunDefault; // 0: Not run default, 1: Cpu Change, 2:Watch Dog timeout
+} OVERCLOCKING_CONFIG_DATA;
+
+typedef struct _OVERCLOCKING_CONFIG_HOB {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ OVERCLOCKING_CONFIG_DATA OverclockData;
+} OVERCLOCKING_CONFIG_HOB;
+
+typedef struct {
+ UINT8 MaxNonTurboRatio;
+} CPU_RATIO_LIMIT_DATA;
+
+typedef struct _CPU_RATIO_LIMIT_HOB {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ CPU_RATIO_LIMIT_DATA CpuRatioLimitData;
+ BOOLEAN IsChangeCpu;
+} CPU_RATIO_LIMIT_HOB;
+
+#pragma pack()
+
+#endif //end of #if PERF_TUNE_SUPPORT == 1
+#endif //end of #ifdef PERF_TUNE_SUPPORT == 1
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-20113, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuCspLib.c b/Core/CPU/CpuCspLib.c
new file mode 100644
index 0000000..549d979
--- /dev/null
+++ b/Core/CPU/CpuCspLib.c
@@ -0,0 +1,2461 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuCspLib.c 6 5/22/15 6:07a Crystallee $
+//
+// $Revision: 6 $
+//
+// $Date: 5/22/15 6:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuCspLib.c $
+//
+// 6 5/22/15 6:07a Crystallee
+// [TAG] EIP219394
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Static code analysis issues found in Aptio4 Intel Haswell
+// module
+// [RootCause] Didn't update register content.
+// [Solution] Update register content.
+//
+// 5 8/14/13 4:55a Davidhsieh
+// [TAG] EIP131295
+// [Category] Improvement
+// [Description] Add token to force turbo mode is not supported for i3
+// Cpu
+//
+// 4 2/07/13 3:56a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] add IsPowerCycle function.
+//
+// 3 11/23/12 2:08a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 2 8/21/12 11:28p Davidhsieh
+// [TAG] None
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] EFI_SMM_CPU_PROTOCOL-> ReadSaveState can't get CR4 value
+// [RootCause] The index for CR4 is incorrect.
+//
+// [Solution] Correct the index value
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuCspLib.c
+//
+// Description:
+// Contains the CPU library related functions. These functions can be linked
+// with various components in the project.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <efi.h>
+#include <token.h>
+#include <AmiDxeLib.h>
+#include <smm.h>
+#include <Pcie.h>
+
+#include "Cpu.h"
+#include "CpuCspLib.h"
+#include "AmiCspLibInc.h"
+
+#ifndef FV_MICROCODE_BASE
+#define FV_MICROCODE_BASE FV_MAIN_BASE
+#endif
+
+#define MAX_NR_BUS ((PCIEX_LENGTH/0x100000)-1)
+
+static EFI_GUID gMicrocodeFfsGuid =
+ {0x17088572, 0x377F, 0x44ef, 0x8F, 0x4E, 0xB0, 0x9F, 0xFF, 0x46, 0xA0, 0x70};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsPowerCycle
+//
+// Description: If Power Cycle is or not.
+//
+// Input:
+// NULL
+//
+// Output:
+// UINT8 , 0 - Not Power Cycle
+// 1 - Power Cycle
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 IsPowerCycle(){
+ //
+ // This is the sample code for Sharkbay with Lynx Point(ver0.7.0 spec.)
+ // Please program properly for your platform
+ //
+ UINT16 Buff16;
+ Buff16 = READ_PCI16_SB(0xA2);
+
+ if (((Buff16 & BIT5) != 0) /*&& ((Buff16 & BIT7) != 0)*/)
+ {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PchPmTimerStall
+//
+// Description: Delay N*Usec
+//
+// Input: UINTN Usec
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PchPmTimerStall (IN UINTN Usec)
+{
+ UINTN Counter = Usec * 3;
+ UINTN i;
+ UINT32 Data32;
+ UINT32 PrevData;
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData=Data32;
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PollMailboxReady
+//
+// Description: Return OC Mailbox is ready or busy.
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: UINT8 (1: busy, 0: ready)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 PollMailboxReady()
+{
+ UINT64 MsrData;
+ UINT32 WaitTime = 1000;
+
+ do{
+ MsrData = ReadMsr(0x150); //Overclock Mailbox: 0x150
+ if(!(Shr64(MsrData,63) & 0x1)) break;
+ //gStallPpi->Stall(gPeiServices, gStallPpi, 1000); //delay 1ms
+ PchPmTimerStall(1000); //delay 1ms
+ WaitTime--;
+ }while((Shr64(MsrData,63) & 0x1) && WaitTime>0); //check run/busy bit, 1 is busy
+
+ if((Shr64(MsrData,63) & 1) && WaitTime == 0)
+ return 1; //busy
+ else
+ return 0; //ready
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadMSR150
+//
+// Description: Return Msr0x150 data
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadMSR150(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ UINT64 MsrDataVerify;
+
+ MsrData = ReadMsr(0x150);
+
+ //gStallPpi->Stall(gPeiServices, gStallPpi, 10000); //wait 10ms
+ PchPmTimerStall(10000); //delay 1ms
+
+ MsrDataVerify = ReadMsr(0x150);
+
+ if((UINT32)MsrData != (UINT32)MsrDataVerify) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetOcCapability
+//
+// Description: Get the overclocking capabilities for a given CPU Domain
+// by reading/writing MSR 0x150
+//
+// Input: UINT8 DomainID (0:IA, 1:GT, 2:Ring, 3:SA, 4:IOD, 5:IOA)
+// UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetOcCapability(IN UINT8 DomainID, OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(DomainID,40); //Param1
+ MsrData |= Shl64(0x01,32); //Command, Overclocking Capability
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSVIDConfig
+//
+// Description: Get the SVID Configuration information
+// by reading/writing MSR 0x150
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetSVIDConfig(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(0,40); //Param1, 0 = IVR input
+ MsrData |= Shl64(0x12,32); //Command, Read SVID Config
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetVoltFreq
+//
+// Description: Gets the Voltage and Frequency information for a given CPU domain
+// by reading/writing MSR 0x150
+//
+// Input: UINT8 DomainID (0:IA, 1:GT, 2:Ring)
+// UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetVoltFreq(IN UINT8 DomainID, OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(DomainID,40); //Param1, 0 = IVR input
+ MsrData |= Shl64(0x10,32); //Command, Read Voltage/Frequency
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFIVRConfig
+//
+// Description: Get the FIVR Configuration information
+// by reading/writing MSR 0x150
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFIVRConfig(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(0x0,40); //Param1
+ MsrData |= Shl64(0x14,32); //Command, Read Misc Global Config
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isBCLKRatioSuuported
+//
+// Description: Determine if CPU supports BCLK coarse ratio support.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isBCLKRatioSuuported()
+{
+ UINT32 PciAddress;
+
+// PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x0) << 11) | ((0x0) << 8) | 0xE4;
+ PciAddress = (0x1) << 31 | 0xE4;
+ IoWrite32(0x0cf8,PciAddress);
+ if ( IoRead32(0x0cfc) & BIT18 ){
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuSignature
+//
+// Description: Get the cpu signature.
+//
+// Input: VOID
+//
+// Output: Cpu Signature
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuSignature()
+{
+ UINT32 CpuSignature, CpuIdEBX, CpuIdECX, CpuIdEDX;
+ CPULib_CpuID(1, &CpuSignature, &CpuIdEBX, &CpuIdECX, &CpuIdEDX);
+ return CpuSignature;
+}
+
+typedef struct {
+ UINT32 Stepping:4;
+ UINT32 Model:4;
+ UINT32 Family:4;
+ UINT32 Type:2;
+ UINT32 RV:2;
+ UINT32 ExtModel:4;
+ UINT32 ExtFamily:8;
+} CPU_SIGNATURE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuFamily
+//
+// Description: Get the cpu family from signature.
+//
+// Input: UINT32 CpuSignature
+//
+// Output: UINT32 - Cpu Family
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuFamily(UINT32 CpuSignature)
+{
+ CPU_SIGNATURE *Signature = (CPU_SIGNATURE*)&CpuSignature;
+ return Signature->ExtFamily + Signature->Family;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuModel
+//
+// Description: Get the cpu model from signature.
+//
+// Input: UINT32 CpuSignature
+//
+// Output: UINT32 - Cpu Model
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuModel(UINT32 CpuSignature)
+{
+ CPU_SIGNATURE *Signature = (CPU_SIGNATURE*)&CpuSignature;
+ return (Signature->ExtModel << 4) + Signature->Model;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuPlatformId
+//
+// Description: Get the cpu platform Id.
+//
+// Input: VOID
+//
+// Output: Cpu Platform Id
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetCpuPlatformId(VOID)
+{
+ return (UINT32)Shr64(ReadMsr(0x17), 50) & 7;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmrrBaseMsr
+//
+// Description: Return the Smrr Base Msr
+//
+// Input: VOID
+//
+// Output: SMRR Base
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetSmrrBaseMsr()
+{
+ return 0x1f2;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadWriteMsr
+//
+// Description: This function writes the CPU MSR with the value provided.
+//
+// Input:
+// Msr 32bit MSR index
+// Value 64bit OR Value
+// Mask 64Bit AND Mask Value
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ReadWriteMsr(UINT32 Msr, UINT64 Value, UINT64 Mask)
+{
+ UINT64 OrigData = ReadMsr(Msr);
+ UINT64 WriteData = (OrigData & Mask) | Value;
+ WriteMsr(Msr, WriteData);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumSupportedThreadsPerCore
+//
+// Description: Get number of supported threads per core.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of Threads per core.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumSupportedThreadsPerCore()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ RegEcx = 0;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ return (UINT8)RegEbx;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumSupportedCpuCores
+//
+// Description: Get number of supported Cpu Cores per package.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of supported Cpu Cores per package.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumSupportedCpuCores()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 TotLogicalCpus;
+ UINT8 LogicalCpusPerCore;
+
+ RegEcx = 1;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ TotLogicalCpus = (UINT8)RegEbx;
+
+ RegEcx = 0;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ LogicalCpusPerCore = (UINT8)RegEbx;
+
+ return TotLogicalCpus / LogicalCpusPerCore;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumLogicalCpus
+//
+// Description: Get number of logical CPUs.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of logical CPUs.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumLogicalCpus()
+{
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ return (UINT8)MsrData;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHtEnabled
+//
+// Description: Determine if CPU is HT.
+//
+// Input: VOID
+//
+// Output: True if HT CPU.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsHtEnabled()
+{
+ UINT8 NumLogCPUs, NumCpuCores;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ UINT32 CpuSignature = GetCpuSignature() & 0xfffffff0;
+
+ NumCpuCores = (UINT8)((UINT32)MsrData >> 16);
+
+ // Westmere work around
+ if (CpuSignature == WESTMERE) NumCpuCores &= 0xf;
+
+ NumLogCPUs = (UINT8)MsrData;
+
+ if ((NumLogCPUs / NumCpuCores) <= 1) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumCpuCores
+//
+// Description: Returns number of CPU Cores
+//
+// Input: VOID
+//
+// Output: Number of CPU Cores.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumCpuCores()
+{
+ UINT32 CpuSignature = GetCpuSignature() & 0xfffffff0;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ UINT8 NumCpuCores = (UINT8)((UINT32)MsrData >> 16);
+
+ // Westmere work around
+ if (CpuSignature == WESTMERE) NumCpuCores &= 0xf;
+
+ return NumCpuCores;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHt0
+//
+// Description: Determine if CPU thread is logical CPU 0 executing.
+//
+// Input: VOID
+//
+// Output: True if logical CPU 0.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsHt0()
+{
+ UINT32 ApicMask;
+ UINT32 ApicId;
+ UINT8 ThreadsPerCore = NumSupportedThreadsPerCore();
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ if (ThreadsPerCore < 2) return TRUE; //Check if Ht Capable.
+ ApicMask = ThreadsPerCore - 1;
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ ApicId = RegEbx >> 24;
+
+ //Use APIC ID to determine if logical CPU.
+ if ((ApicId & ApicMask) == 0) return TRUE; //All logical CPU0 will have bit 0 clear.
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsCore0
+//
+// Description: Determine if CPU thread is CPU Core 0 executing.
+//
+// Input: VOID
+//
+// Output: True if logical CPU 0.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsCore0()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 MaxThreadsPackage;
+ UINT32 ApicMask;
+ UINT32 ApicId;
+
+ ApicMask = ~(NumSupportedThreadsPerCore() - 1);
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ MaxThreadsPackage = (UINT8)(RegEbx >> 16);
+
+ ApicMask &= MaxThreadsPackage - 1;
+ ApicId = RegEbx >> 24;
+
+ //Use APIC ID to determine if logical CPU.
+ if ((ApicId & ApicMask) == 0) return TRUE;
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsX64Supported
+//
+// Description: Determine if CPU supports X64.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsX64Supported(CPU_FEATURES *Features)
+{
+ return ((Features->ExtFeatureEdx) >> 29) & 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXDSupported
+//
+// Description: Determine if CPU supports Execute Disable.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN isXDSupported(CPU_FEATURES *Features)
+{
+ return !!(Features->ExtFeatureEdx & (1 << 20));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isTurboModeSupported
+//
+// Description: Determine if CPU supports Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isTurboModeSupported()
+{
+ BOOLEAN ret;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ UINT64 MsrData = ReadMsr(MSR_IA32_MISC_ENABLE);
+
+#if defined(I3_CPU_NON_TURBO) && (I3_CPU_NON_TURBO == 1)
+{
+ CHAR8 BrandStrBuff[49];
+ CHAR8 *BrandString = BrandStrBuff;
+
+ CPULib_CpuID(0x80000002, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+
+
+ CPULib_CpuID(0x80000003, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+
+ CPULib_CpuID(0x80000004, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+ *BrandString = '\0';
+
+ BrandString = BrandStrBuff;
+
+ while(*BrandString) {
+ if (MemCmp(BrandString, "i3", 2) == 0) return FALSE;
+ ++BrandString;
+ }
+}
+#endif
+ CPULib_CpuID(6, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ ret = ((RegEax >> 1) & 1) | (UINT32) (Shr64(MsrData,TURBO_MODE_DISABLE_BIT) & 1);
+ return ret;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isFullUnlockCpuSuuported
+//
+// Description: Determine if CPU supports Full unlock.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isFullUnlockCpuSuuported()
+{
+ UINT64 MsrData = ReadMsr(MSR_FLEX_RATIO);
+
+ if((UINT32)(Shr64(MsrData, 17)) == 0x7) return TRUE;
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXETdcTdpLimitSupported
+//
+// Description: Determine if CPU supports Programmable TDC/TDP Limit for the Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isXETdcTdpLimitSupported()
+{
+
+ BOOLEAN ret;
+ UINT64 MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ ret = (UINT32) (MsrData & (1 << XE_TDP_TDC_PROGRAMMABLE_BIT)) ? 1:0;
+ return ret;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXECoreRatioLimitSupported
+//
+// Description: Determine if CPU supports Programmable Core Ratio Limit for the Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ BOOLEAN isXECoreRatioLimitSupported()
+ {
+
+ BOOLEAN ret;
+ UINT64 MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ ret = (UINT32) (MsrData & (1 << XE_CORE_RATIO_PROGRAMMABLE_BIT)) ? 1:0;
+ return ret;
+ }
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isLimitCpuidSupported
+//
+// Description: Determine if CPU supports limiting CpuId to 3.
+//
+// Input: VOID
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN isLimitCpuidSupported()
+{
+ UINT32 RegEbx, RegEcx, RegEdx;
+ UINT32 LargestCPUIDFunc;
+ CPULib_CpuID(0, &LargestCPUIDFunc, &RegEbx, &RegEcx, &RegEdx);
+ return LargestCPUIDFunc > 3;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isMachineCheckSupported
+//
+// Description: Determine if CPU supports machine check.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsMachineCheckSupported(CPU_FEATURES *Features)
+{
+ //Check if MCE and MCA supported.
+ return ((Features->FeatureEdx & ((1 << 7) + (1 << 14))) == ((1 << 7) + (1 << 14)));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsVmxSupported
+//
+// Description: Determine if CPU supports VT extensions Vmx.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Vmx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsVmxSupported(CPU_FEATURES *Features)
+{
+ return Features->FeatureEcx & (1 << 5);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSmxSupported
+//
+// Description: Determine if CPU supports VT extensions Smx.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Smx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSmxSupported(CPU_FEATURES *Features)
+{
+ return Features->FeatureEcx & (1 << 6);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_IsSmrrSupported
+//
+// Description: Determine if CPU supports Smrr.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Smx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSmrrSupported(CPU_FEATURES *Features)
+{
+ return (BOOLEAN)Features->Flags.SmrrSupport;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsEnergyPerfBiasSupported
+//
+// Description: Determine if Energy Performance Bias supported.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if Energy Performance Bias supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+// BOOLEAN IsEnergyPerfBiasSupported()
+// {
+// UINT32 RegEax;
+// UINT32 RegEbx;
+// UINT32 RegEcx;
+// UINT32 RegEdx;
+//
+// UINT32 CpuSignature = GetCpuSignature();
+// UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+// UINT32 CpuVer = CpuSignature & 0xf;
+//
+// BOOLEAN Support = FALSE;
+//
+// //This is also used to control setup question. No recommendation in BWG.
+// //Thus, for now Sandy Bridge Energy Bias Support is coded separately from previous CPUs.
+// //if (CpuSigNoVer == SANDY_BRIDGE && CpuVer >= 3)
+// // return TRUE;
+//
+// if (CpuSigNoVer == NEHALEM_EX && CpuVer >= 5) Support = TRUE;
+// else if (CpuSigNoVer == WESTMERE) Support = TRUE;
+// else if (CpuSigNoVer == WESTMERE_EX) Support = TRUE;
+//
+// if (!Support) return FALSE;
+// ReadWriteMsr(MSR_MISC_PWR_MGMT, (1 << ENG_PERF_BIAS_EN_BIT), (UINT64)-1); //Energy Performance Bias Enable
+//
+// CPULib_CpuID(6, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+// return !!(RegEcx & BIT3);
+// }
+//
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsCxInterruptFilteringSupported
+//
+// Description: Determine if C-state interrupting state supported.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if C-state interrupting supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+// BOOLEAN IsCxInterruptFilteringSupported()
+// {
+// return FALSE;
+//
+// //Not supported until this is used on a project that can test this functionality.
+// //DEBUG UINT32 CpuSignature = GetCpuSignature();
+// //DEBUG if (CpuSignature != 0x00020652) return FALSE;
+// //DEBUG if ((INT32)Shr64(ReadMsr(MSR_IA32_BIOS_SIGN_ID), 32) < 3) return FALSE;
+// //DEBUG return TRUE;
+// }
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsVmxEnabled
+//
+// Description: Determine if Vmx is enabled.
+//
+// Input: VOID
+//
+// Output: True if Vmx enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsVmxEnabled()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 Msr;
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if (!(RegEcx & (1 << 5))) return FALSE;
+
+ Msr = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return !!(Msr & (1 << 2));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsSmxEnabled
+//
+// Description: Determine if Smx is enabled.
+//
+// Input: VOID
+//
+// Output: True if Smx enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsSmxEnabled()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 Msr;
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if (!(RegEcx & BIT6)) return FALSE;
+
+ Msr = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return !!(Msr & BIT1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsSmrrEnabled
+//
+// Description: Determine if Smrr is enabled.
+//
+// Input: BOOLEAN
+//
+// Output: True if Smrr is enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsSmrrEnabled()
+{
+ //Once SMRR is enabled, the opened SMM Area can't be read outside of SMM.
+#if SMM_CACHE_SUPPORT == 0
+ return FALSE;
+#else
+ //Some CPUs, SMRR has an enable bit. Nehalem only has a capability bit.
+ UINT32 MtrrCap = (UINT32)ReadMsr(MSR_IA32_MTRR_CAP);
+ return !!(MtrrCap & SMRR_SUPPORT_MASK);
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_IsLocalX2ApicEnabled
+//
+// Description: Get C-state latency.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if enabled
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CPULib_IsLocalX2ApicEnabled()
+{
+ UINT32 Msr = (UINT32)ReadMsr(MSR_XAPIC_BASE);
+ return !!(Msr & (1 << XAPIC_X2APIC_ENABLE_BIT));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsFeatureControlLocked
+//
+// Description: Check to see if the MSR_IA32_FEATURE_CONTROL is locked.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if MSR_IA32_FEATURE_CONTROL is locked.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsFeatureControlLocked() {
+ UINT8 Ia32FeatureCntrl = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return Ia32FeatureCntrl & 1;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumberOfCpuSocketsPopulated
+//
+// Description: Returns number of CPU sockets are populated.
+//
+// Input: VOID
+//
+// Output: UINT32 - Number of CPU sockets populated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 NumberOfCpuSocketsPopulated()
+{
+#if NUMBER_CPU_SOCKETS > 1
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT32 NumCpuSockets = 0;
+ UINT32 i;
+ UINT32 BusNum;
+
+ //Sandy Bridge Server.
+ if (CpuSigNoVer == JAKETOWN) {
+ UINT32 *PciAddress = (UINT32*)PCIE_CFG_ADDR(0, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#if NUMBER_CPU_SOCKETS >= 4
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0x40, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#endif
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0x80, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#if NUMBER_CPU_SOCKETS >= 4
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0xc0, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#endif
+ return NumCpuSockets;
+ }
+ for (i = 0, BusNum = MAX_NR_BUS; i < NUMBER_CPU_SOCKETS; ++i, --BusNum) {
+ UINT32 *PciAddress = (UINT32*)PCIE_CFG_ADDR(BusNum, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+ }
+ return NumCpuSockets;
+#else
+ return 1;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_GetCstateLatency
+//
+// Description: Get C-state latency.
+//
+// Input: IN UINT8 Cstate
+//
+// Output: UINT32 - C-state latentcy in uS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULIB_GetCstateLatency(IN UINT8 Cstate)
+{
+ UINT32 CpuSigNoVer = GetCpuSignature() & 0xfffffff0;
+ BOOLEAN IsSandyBridge = CpuSigNoVer == SANDY_BRIDGE || CpuSigNoVer == JAKETOWN || CpuSigNoVer == IVY_BRIDGE;
+
+ if (IsSandyBridge) {
+ switch(Cstate) {
+ case 1: return 1;
+ case 3: return 80;
+ case 6: return 104;
+ case 7: return 109;
+ }
+ }
+
+ switch(Cstate) {
+ case 1: return 3;
+ case 3: return 205;
+ case 6: return 245;
+ case 7: return 245;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_GetCstatePower
+//
+// Description: Get C-state power.
+//
+// Input: IN UINT8 Cstate
+//
+// Output: UINT32 - C-state power in mW.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULIB_GetCstatePower(IN UINT8 Cstate)
+{
+ switch(Cstate) {
+ case 1: return 1000;
+ case 3: return 500;
+ case 6: return 350;
+ case 7: return 200;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_FindMicrocodeInFv
+//
+// Description: Find the microcode address for the CPU calling this in specific firmware volume.
+//
+// Input: VOID *Fv -- Firmware Volume
+//
+// Output: VOID * -- 0 if not found or the Microcode Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * CPULib_FindMicrocodeInFv(VOID *Fv)
+{
+ UINT8 *pEndOfFv = (UINT8*)Fv + ((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->FvLength - 1;
+ UINT8 *pFfs = (UINT8*)Fv + ((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->HeaderLength;
+ UINT8 *pEndOfFfs;
+ UINT32 FfsSize;
+
+ MICROCODE_HEADER *pUc;
+ UINT32 UcSize;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT8 CpuFlags = (UINT8)(Shr64(ReadMsr(0x17), 50)) & 7;
+ UINT8 UcFlag = 1 << CpuFlags;
+
+ //Check for corrupt firmware volume.
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Signature != 'HVF_') return 0;
+ if (pEndOfFv <= pFfs) return 0;
+
+ while(TRUE) {
+ if (*(UINT32*)pFfs == 0xffffffff) return 0;
+ if (pFfs >= pEndOfFv) return 0;
+
+ FfsSize = *(UINT32*)&((EFI_FFS_FILE_HEADER*)pFfs)->Size & 0xffffff;
+
+ //Find Microcode file
+ if (guidcmp(&((EFI_FFS_FILE_HEADER*)pFfs)->Name, &gMicrocodeFfsGuid) == 0)
+ break;
+ if ((pFfs + FfsSize) <= pFfs) return 0; //Corruption?
+ pFfs += FfsSize; //Next file.
+ pFfs = (UINT8*)(((UINT32)pFfs + 7) & ~7); //Align on 8 byte boundary.
+ }
+
+ pEndOfFfs = pFfs + FfsSize;
+#if MPDTable_CREATED
+ pEndOfFfs -= *(UINT16*)(pEndOfFfs - 2); //Last 2 bytes is MPDT Length. Don't look in the MPDT for uC.
+#endif
+
+ //Find Microcode
+ pUc = (MICROCODE_HEADER*)(pFfs + sizeof(EFI_FFS_FILE_HEADER));
+
+ while(TRUE) {
+ if (pUc->HeaderVersion != 1) return 0; //End of microcode or corrupt.
+ UcSize = pUc->DataSize ? pUc->TotalSize : 2048;
+
+ if (pUc->CpuSignature == CpuSignature && (pUc->Flags & UcFlag))
+ break;
+
+ if (pUc->TotalSize > (pUc->DataSize + 48)) { //Extended signature count.
+ MICROCODE_EXT_PROC_SIG_TABLE *SigTable = (MICROCODE_EXT_PROC_SIG_TABLE*)((UINT8*)pUc + pUc->DataSize + 48);
+ UINT32 ExtSigCount = SigTable->Count;
+ UINT8 i;
+
+ if (ExtSigCount >= 20) return 0; //Corrupt microcode.
+
+ for (i = 0; i < ExtSigCount; ++i) {
+ if (SigTable->ProcSig[i].CpuSignature == CpuSignature && (SigTable->ProcSig[i].Flags & UcFlag)) break;
+ }
+ }
+
+#if PACK_MICROCODE
+ UcSize = (UcSize + (16 - 1)) & ~(16 - 1);
+#else
+ UcSize = (UcSize + (MICROCODE_BLOCK_SIZE - 1)) & ~(MICROCODE_BLOCK_SIZE - 1);
+#endif
+ if (((UINT64)(UINTN)pUc + UcSize) >= (UINT64)(UINTN)pEndOfFfs) return 0; //End of uc or corrupt
+
+ pUc = (MICROCODE_HEADER*)((UINT8*)pUc + UcSize);
+ }
+ return pUc;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_FindMicrocode
+//
+// Description: Find the microcode address for the CPU calling this.
+//
+// Input: VOID
+//
+// Output: VOID * -- 0 if not found or the Microcode Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * CPULib_FindMicrocode()
+{
+ VOID *Microcode;
+#if MICROCODE_SPLIT_BB_UPDATE
+ Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_UPDATE_BASE);
+ if (Microcode == NULL) Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_BASE);
+#else
+ Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_BASE);
+#endif
+ return Microcode;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_GetMicrocodeVer
+//
+// Description: Get Microcode Version
+//
+// Input: VOID
+//
+// Output: UINT32 - Microcode Version
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULib_GetMicrocodeVer()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ //Clear IA32_BIOS_SIGN_ID of microcode loaded.
+ WriteMsr(MSR_IA32_BIOS_SIGN_ID, 0);
+
+ //Reading CPU ID 1, updates the MSR to the microcode revision.
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ return (UINT32)Shr64(ReadMsr(MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmBaseChangeCopy
+//
+// Description: This is SMM code copied to 3000:8000 to set the SmmBase and IED.
+//
+// Input: None
+//
+// Output: None
+//
+// Notes:
+// This is in real mode. To generate 16-bit code opcodes, use a small asm
+// file to generate a listing.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//TODO: Move this array into assembly file. It is getting too big.
+UINT8 SmmBaseChangeCopy[] =
+{ //cs = 0x3000
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8000 mov eax, SMM_BASE
+ 0xbb, 0x00, 0x00, //0x8006 mov bx, 0 ;Location SM BASE OFFSET
+ 0x66, 0x2e, 0x89, 0x07, //0x8009 mov cs:[bx], eax
+
+ 0x66, 0xbb, 0x01, 0x00, 0x00, 0x00, //0x800d mov ebx, 1
+ 0x67, 0x66, 0x89, 0x98, 4,0x80,0,0, //0x8013 mov [eax + 8004h], ebx ;Set SMM initialization
+ 0x66, 0xb8, 0xff, 0xff, 0xff, 0xff, //0x801b mov eax, IED_BASE
+ 0xbb, 0x00, 0x00, //0x8021 mov bx, 0 ;Location of IED_SAVESTATE_OFFSET
+ 0x66, 0x2e, 0x89, 0x07, //0x8024 mov cs:[bx], eax
+
+ 0xbb, 0x00, 0x00, //0x8028 mov bx, 0
+ 0x0b, 0xdb, //0x802b or bx, bx
+ 0x75, 0x32, //0x802d jnz FirstIedInit
+
+ 0x66, 0x89, 0xc3, //0x802f mov ebx, eax
+ 0x66, 0x8b, 0xf8, //0x8032 mov edi, eax
+ 0x66, 0x81, 0xc7, 0x0, 0, 0x10, 0, //0x8035 add edi, 0x10 0000
+ 0x66, 0xb9, 0x00, 0x20, 0x00, 0x00, //0x803c mov ecx, 32 * 1024 /4
+ 0x66, 0x33, 0xc0, //0x8042 xor eax, eax
+//@@:
+ 0x66, 0x67, 0xab, //0x8045 stosd //clear IED 32k
+ 0x67, 0xe2, 0xfa, //0x8048 loop @b
+
+ 0x66, 0x89, 0xdf, //0x804b mov edi, ebx
+ 0x66, 0x81, 0xc7, 0x0, 0, 0x20, 0, //0x804e add edi, 0x20 0000
+ 0x66, 0xb9, 0x00, 0x00, 0x08, 0x00, //0x8055 mov ecx, 0x200000 / 4
+//@@:
+ 0x66, 0x67, 0xab, //0x805b stosd //clear IED 2MB
+ 0x67, 0xe2, 0xfa, //0x805e loop @b
+
+//FirstIedInit:
+
+ 0xeb, 0x24, //0x8061 jmp NO_SMRR ;If SMRR, this will be changed to NOPs.
+//SMRR:
+ 0x66, 0xb9, 0x00, 0x00, 0x00, 0x00, //0x8063 mov ecx, 0 ;MSR_SMRR_PHYS_BASE will be updated after copy.
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8069 mov eax, 0 ;This will be updated after copy.
+ 0x66, 0xba, 0x00, 0x00, 0x00, 0x00, //0x806f mov edx, 0 ;This will be updated after copy.
+ 0x0f, 0x30, //0x8075 wrmsr
+ 0x66, 0x41, //0x8077 inc ecx ;MSR_SMRR_PHYS_MASK
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8079 mov eax, 0 ;This will be updated after copy.
+ 0x66, 0xba, 0x00, 0x00, 0x00, 0x00, //0x807f mov edx, 0 ;This will be updated after copy.
+ 0x0f, 0x30, //0x8085 wrmsr
+//NO_SMRR:
+ 0xb0, 0x01, //0x8087 mov al, 1
+ 0x2e, 0xa2, 0x8f, 0x80, //0x8089 mov cs:[0x8076], al ;set flag
+ 0x0f, 0xaa, //0x808d rsm
+ 0x00 //0x808f SmmBaseChangeFlag label byte
+};
+
+#define SMM_ASM_FIXUP_SMM_BASE 0x38002
+#define SMM_ASM_FIXUP_SMM_BASE_SAVESTATE_OFFSET 0x38007
+#define SMM_ASM_FIXUP_IED_BASE 0x3801d
+#define SMM_ASM_FIXUP_IED_SAVESTATE_OFFSET 0x38022
+#define SMM_ASM_FIXUP_IED_ZERO_MEM 0x38029
+#define SMM_ASM_FIXUP_USE_SMRR 0x38061
+#define SMM_ASM_FIXUP_MSR_SMRR_BASE 0x38065
+#define SMM_ASM_FIXUP_SMRR_BASE_EAX 0x3806b
+#define SMM_ASM_FIXUP_SMRR_BASE_EDX 0x38071
+#define SMM_ASM_FIXUP_SMRR_MASK_EAX 0x3807b
+#define SMM_ASM_FIXUP_SMRR_MASK_EDX 0x38081
+#define SMM_ASM_BASE_CHANGE_FLAG 0x3808f
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmGetBaseSaveBufferSize
+//
+// Description: Return about of memory required for the SMM handler change.
+//
+// Input: VOID
+//
+// Output:
+// UINT32 Amount of memory required for SMM handler change.
+//
+// Notes:
+// The memory will need to be allocated to use in SmmSetupDefaultHandler.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 SmmGetBaseSaveBufferSize()
+{
+ return sizeof(SmmBaseChangeCopy) + MAX_SMM_SAVE_STATE_SIZE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmSetupDefaultHandler
+//
+// Description: Save original memory, and copy SMM default handler.
+//
+// Input:
+// IN VOID *SmmBaseSaveBuffer
+// IN SMM_HOB *SmmHob
+//
+// Output:
+// VOID
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmSetupDefaultHandler(IN VOID *SmmBaseSaveBuffer, IN SMM_HOB *SmmHob)
+{
+ //Perserve 3000:8000 used by SMM. It will be overwritten.
+ MemCpy(SmmBaseSaveBuffer, (VOID*)0x38000, sizeof(SmmBaseChangeCopy));
+
+ MemCpy((UINT8*)SmmBaseSaveBuffer + sizeof(SmmBaseChangeCopy), (UINT8*)0x40000 - MAX_SMM_SAVE_STATE_SIZE, MAX_SMM_SAVE_STATE_SIZE);
+ MemCpy((VOID*)0x38000, SmmBaseChangeCopy, sizeof(SmmBaseChangeCopy));
+
+ *(UINT16*)SMM_ASM_FIXUP_SMM_BASE_SAVESTATE_OFFSET = SMM_BASE_SAVE_STATE_OFFSET;
+ *(UINT16*)SMM_ASM_FIXUP_IED_SAVESTATE_OFFSET = IED_SAVESTATE_OFFSET;
+ *(UINT32*)SMM_ASM_FIXUP_IED_BASE = SmmHob->IedStart; //IED Start
+
+ //Initialize SMRR
+ if(CPULib_IsSmrrEnabled()) { //Could be disabled. Reset may not clear lock.
+ UINT64 TsegMask = (0xfffffffff & (~(SmmHob->TsegLength - 1))) | (1 << 11);
+ *(UINT16*)SMM_ASM_FIXUP_USE_SMRR = 0x9090; //Jmp changed to NOPs.
+ //Update SMRR MSR.
+ *(UINT32*)SMM_ASM_FIXUP_MSR_SMRR_BASE = GetSmrrBaseMsr();
+ //Update SMRR Base
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_BASE_EAX = (UINT32)SmmHob->Tseg | 6; //Lower 32-bits. 6 = WB.
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_BASE_EDX = 0; //Upper 32-bits.
+ //Update SMRR Mask
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_MASK_EAX = (UINT32)TsegMask; //Lower 32-bits.
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_MASK_EDX = 0; //Upper 32-bits. SMRR Mask Reserved bits.
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmBaseChangeOnCpu
+//
+// Description: Execute on each CPU to change its own base.
+//
+// Input:
+// VOID *SmmBase
+//
+// Output:
+// VOID
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmBaseChangeOnCpu(IN VOID *SmmBase)
+{
+ *(UINT32*)SMM_ASM_FIXUP_SMM_BASE = (UINT32)SmmBase;
+ *(UINT8*)SMM_ASM_BASE_CHANGE_FLAG = 0; //Initialize Flag
+
+ //Send SMM IPI
+ if (CPULib_IsLocalX2ApicEnabled()) {
+ UINT32 ApicId = (UINT32) ReadMsr(MSR_EXT_XAPIC_LOGICAL_APIC_ID);
+ ReadWriteMsr(MSR_EXT_XAPIC_ICR,
+ Shl64(ApicId, 32) + APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI,
+ 0xfff32000
+ );
+ } else {
+ UINT8 ApicId = (UINT8)(*(UINT32*)(LOCAL_APIC_BASE + APIC_ID_REGISTER) >> 24);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER), ApicId << 24, 0x00ffffff);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER), APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI, 0);
+ }
+
+ while (!(*(volatile UINT8*)SMM_ASM_BASE_CHANGE_FLAG)) CPULib_Pause(); //Wait on Flag
+ ++*(UINT16*)SMM_ASM_FIXUP_IED_ZERO_MEM; //Only 0, for first thread to clear IED memory.
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmRemoveDefaultHandler
+//
+// Description: Remove default SMM Handler from memory and restore original data.
+//
+// Input:
+// IN VOID *SmmBaseSaveBuffer
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmRemoveDefaultHandler(IN VOID *SmmBaseSaveBuffer)
+{
+ //Restore 3000:8000 overwritten for SMM
+ MemCpy((VOID*)0x38000, SmmBaseSaveBuffer, sizeof(SmmBaseChangeCopy));
+ MemCpy((UINT8*)0x40000 - MAX_SMM_SAVE_STATE_SIZE, (UINT8*)SmmBaseSaveBuffer + sizeof(SmmBaseChangeCopy), MAX_SMM_SAVE_STATE_SIZE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPUProgramPAMRegisters
+//
+// Description: Program 0xc0000 - 0xfffff regions to Lock/Unlock.
+//
+// Input:
+// UINT32 StartAddress
+// UINT32 Length
+// UINT8 Setting
+// UINT32 *Granularity
+//
+// Output: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPUProgramPAMRegisters(
+ EFI_BOOT_SERVICES *gBS,
+ EFI_RUNTIME_SERVICES *gRS,
+ UINT32 StartAddress,
+ UINT32 Length,
+ UINT8 Setting,
+ UINT32 *Granularity
+)
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SaveCpuState
+//
+// Description: Save CPU state in SMM.
+//
+// Input:
+// IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA *State - Track CPU state.
+//
+// Output: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuLib_SmmSaveCpuState(IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA* State)
+{
+ UINT64 ClkMod = ReadMsr(MSR_IA32_CLOCK_MODULATION);
+
+ State->ClkModEn = (UINT8)ClkMod & CLK_MOD_ENABLE;
+ ClkMod &= ~(UINT64)CLK_MOD_ENABLE;
+ WriteMsr(MSR_IA32_CLOCK_MODULATION, ClkMod);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmRestoreCpuState
+//
+// Description: Restore CPU state in SMM.
+//
+// Input:
+// IN CPU_LIB_SMM_SAVE_RESTORE_DATA *State - Track CPU state.
+//
+// Output: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuLib_SmmRestoreCpuState(IN CPU_LIB_SMM_SAVE_RESTORE_DATA* State)
+{
+ if (State->ClkModEn) ReadWriteMsr(MSR_IA32_CLOCK_MODULATION, CLK_MOD_ENABLE, (UINT64)-1);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_GetSaveStateId30006
+//
+// Description:
+// This routines saves the necessary values from Revison 3006
+// SMM save state area.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CPU_GetSaveStateId30006(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState,
+ UINT32 SmmRevision
+)
+{
+ SstSaveState->SMBASE = *(UINT32*)(SmmBase + 0xfef8);
+ SstSaveState->SMMRevId = *(UINT32*)(SmmBase + 0xfefc);
+#if (((CORE_MAJOR_VERSION << 16) + (CORE_MINOR_VERSION << 8) + CORE_REVISION) > 0x040603)
+ SstSaveState->GDTBase = *(UINT32*)(SmmBase + 0xfe8c);
+ SstSaveState->IDTBase = *(UINT32*)(SmmBase + 0xfe94);
+ SstSaveState->CR4 = *(UINT32*)(SmmBase + 0xfe40);
+#endif
+ SstSaveState->ES = *(UINT16*)(SmmBase + 0xffa8);
+ SstSaveState->CS = *(UINT16*)(SmmBase + 0xffac);
+ SstSaveState->SS = *(UINT16*)(SmmBase + 0xffb0);
+ SstSaveState->DS = *(UINT16*)(SmmBase + 0xffb4);
+ SstSaveState->FS = *(UINT16*)(SmmBase + 0xffb8);
+ SstSaveState->GS = *(UINT16*)(SmmBase + 0xffbc);
+ SstSaveState->LDTBase = *(UINT32*)(SmmBase + 0xfe9c);
+ SstSaveState->TR = *(UINT32*)(SmmBase + 0xffc4);
+ SstSaveState->DR7 = *(UINT32*)(SmmBase + 0xffc8);
+ SstSaveState->DR6 = *(UINT32*)(SmmBase + 0xffd0);
+ SstSaveState->EAX = *(UINT32*)(SmmBase + 0xff5c);
+ SstSaveState->ECX = *(UINT32*)(SmmBase + 0xff64);
+ SstSaveState->EDX = *(UINT32*)(SmmBase + 0xff6c);
+ SstSaveState->EBX = *(UINT32*)(SmmBase + 0xff74);
+ SstSaveState->ESP = *(UINT32*)(SmmBase + 0xff7c);
+ SstSaveState->EBP = *(UINT32*)(SmmBase + 0xff84);
+ SstSaveState->ESI = *(UINT32*)(SmmBase + 0xff8c);
+ SstSaveState->EDI = *(UINT32*)(SmmBase + 0xff94);
+ SstSaveState->EIP = *(UINT32*)(SmmBase + 0xffd8);
+ SstSaveState->EFLAGS = *(UINT32*)(SmmBase + 0xffe8);
+ SstSaveState->CR3 = *(UINT32*)(SmmBase + 0xfff0);
+ SstSaveState->CR0 = *(UINT32*)(SmmBase + 0xfff8);
+
+ if (SmmRevision < 0x30100) {
+ SstSaveState->IORestart = *(UINT16*)(SmmBase + 0xff02);
+ SstSaveState->AutoHALTRestart = *(UINT16*)(SmmBase + 0xff00);
+ } else {
+ SstSaveState->AutoHALTRestart = *(UINT16*)(SmmBase + 0xff02);
+ SstSaveState->IORestart = *(UINT16*)(SmmBase + 0xff00);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreSaveStateId30006
+//
+// Description:
+// This routines restores the necessary values from Revision 3006
+// SMM save state area.
+//
+// Input:
+// SmmBase Pointer to SMM save state
+// SstSaveState Standard SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CPU_RestoreSaveStateId30006(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState,
+ UINT32 SmmRevision
+)
+{
+ *(UINT16*)(SmmBase + 0xffa8) = SstSaveState->ES;
+ *(UINT16*)(SmmBase + 0xffac) = SstSaveState->CS;
+ *(UINT16*)(SmmBase + 0xffb0) = SstSaveState->SS;
+ *(UINT16*)(SmmBase + 0xffb4) = SstSaveState->DS;
+ *(UINT16*)(SmmBase + 0xffb8) = SstSaveState->FS;
+ *(UINT16*)(SmmBase + 0xffbc) = SstSaveState->GS;
+ *(UINT32*)(SmmBase + 0xff5c) = SstSaveState->EAX;
+ *(UINT32*)(SmmBase + 0xff64) = SstSaveState->ECX;
+ *(UINT32*)(SmmBase + 0xff6c) = SstSaveState->EDX;
+ *(UINT32*)(SmmBase + 0xff74) = SstSaveState->EBX;
+ *(UINT32*)(SmmBase + 0xff7c) = SstSaveState->ESP;
+ *(UINT32*)(SmmBase + 0xff84) = SstSaveState->EBP;
+ *(UINT32*)(SmmBase + 0xff8c) = SstSaveState->ESI;
+ *(UINT32*)(SmmBase + 0xff94) = SstSaveState->EDI;
+ *(UINT32*)(SmmBase + 0xffd8) = SstSaveState->EIP;
+ *(UINT32*)(SmmBase + 0xffe8) = SstSaveState->EFLAGS;
+
+ if (SmmRevision < 0x30100) {
+ *(UINT16*)(SmmBase + 0xff02) = SstSaveState->IORestart;
+ *(UINT16*)(SmmBase + 0xff00) = SstSaveState->AutoHALTRestart;
+ } else {
+ *(UINT16*)(SmmBase + 0xff02) = SstSaveState->AutoHALTRestart;
+ *(UINT16*)(SmmBase + 0xff00) = SstSaveState->IORestart;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreDefaultSaveState
+//
+// Description:
+// This routines copies the necessary values from standard
+// SMM save state area to version 0x30003 SMM save state area.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_RestoreDefaultSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ EFI_SMI_CPU_SAVE_STATE *SmmSave = (EFI_SMI_CPU_SAVE_STATE*) SmmBase;
+
+ SmmSave->EFLAGS = SstSaveState->EFLAGS;
+ SmmSave->EIP = SstSaveState->EIP;
+ SmmSave->EDI = SstSaveState->EDI;
+ SmmSave->ESI = SstSaveState->ESI;
+ SmmSave->EBP = SstSaveState->EBP;
+ SmmSave->ESP = SstSaveState->ESP;
+ SmmSave->EBX = SstSaveState->EBX;
+ SmmSave->EDX = SstSaveState->EDX;
+ SmmSave->ECX = SstSaveState->ECX;
+ SmmSave->EAX = SstSaveState->EAX;
+ SmmSave->AutoHALTRestart = SstSaveState->AutoHALTRestart;
+ SmmSave->IORestart = SstSaveState->IORestart;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_GetSaveState
+//
+// Description:
+// This routine is the generic routine used to copy the CPU specific SMM
+// save state to standard save state.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_GetSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ UINT32 SmmRevision = *(UINT32*)(SmmBase + 0xfefc);
+
+ //Porting Required. PERFORM CPU SPECIFIC save state handling
+ if (SmmRevision >= 0x30006) {
+ CPU_GetSaveStateId30006(SmmBase, SstSaveState, SmmRevision);
+ } else {
+ UINTN Index;
+ //Copy save state area.
+ for (Index = 0;
+ Index < (sizeof(EFI_SMI_CPU_SAVE_STATE) / sizeof(UINT32));
+ Index ++) {
+ *( ((UINT32 *)SstSaveState) + Index)
+ = *( (UINT32 *)(SmmBase + 0xfe00) + Index);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreSaveState
+//
+// Description:
+// This routine is the generic routine used to copy the standard
+// SMM save state from CPU specific save state. This routine
+// should make sure it does not change read only areas
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_RestoreSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ UINT32 SmmRevision = *(UINT32*)(SmmBase + 0xfefc);
+
+ //Porting Required. PERFORM CPU SPECIFIC save state handling
+ if (SmmRevision >= 0x30006) {
+ CPU_RestoreSaveStateId30006(SmmBase, SstSaveState, SmmRevision);
+ } else {
+ CPU_RestoreDefaultSaveState(SmmBase + 0xfe00, SstSaveState);
+ }
+}
+
+typedef struct {
+ UINT16 SaveStateOffset;
+ UINT16 SaveStateWidth;
+ UINT16 FrameworkOffset;
+ UINT16 FrameworkWidth;
+} INTEL_X64_FORMAT;
+
+INTEL_X64_FORMAT gIntelX64Format[] = {
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10 No Save State
+ 0xffa8, 2, 0x01a8, 2, //EFI_SMM_SAVE_STATE_REGISTER_ES = 20
+ 0xffac, 2, 0x01ac, 2, //EFI_SMM_SAVE_STATE_REGISTER_CS = 21
+ 0xffb0, 2, 0x01b0, 2, //EFI_SMM_SAVE_STATE_REGISTER_SS = 22
+ 0xffb4, 2, 0x01b4, 2, //EFI_SMM_SAVE_STATE_REGISTER_DS = 23
+ 0xffb8, 2, 0x01b8, 2, //EFI_SMM_SAVE_STATE_REGISTER_FS = 24
+ 0xffbc, 2, 0x01bc, 2, //EFI_SMM_SAVE_STATE_REGISTER_GS = 25
+ 0xffc0, 2, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL = 26
+ 0xffc4, 2, 0x01c4, 2, //EFI_SMM_SAVE_STATE_REGISTER_TR_SEL = 27
+ 0xffc8, 8, 0x01c8, 4, //EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28
+ 0xffd0, 8, 0x01fc, 4, //EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29
+ 0xff54, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R8 = 30
+ 0xff4c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R9 = 31
+ 0xff44, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R10 = 32
+ 0xff3c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R11 = 33
+ 0xff34, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R12 = 34
+ 0xff2c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R13 = 35
+ 0xff24, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R14 = 36
+ 0xff1c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R15 = 37
+ 0xff5c, 8, 0x01d0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RAX = 38
+ 0xff74, 8, 0x01dc, 4, //EFI_SMM_SAVE_STATE_REGISTER_RBX = 39
+ 0xff64, 8, 0x01d4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RCX = 40
+ 0xff6c, 8, 0x01d8, 4, //EFI_SMM_SAVE_STATE_REGISTER_RDX = 41
+ 0xff64, 8, 0x01e0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RSP = 42
+ 0xff84, 8, 0x01e4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RBP = 43
+ 0xff8c, 8, 0x01e8, 4, //EFI_SMM_SAVE_STATE_REGISTER_RSI = 44
+ 0xff94, 8, 0x01ec, 4, //EFI_SMM_SAVE_STATE_REGISTER_RDI = 45
+ 0xffd8, 8, 0x01f0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RIP = 46
+ 0xffe8, 8, 0x01f4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51
+ 0xfff8, 8, 0x01fc, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52
+ 0xfff0, 8, 0x01f8, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53
+ 0xfe40, 8, 0x00f0, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR4 = 54
+
+ //Supported in XMM Save/restore function
+ //EFI_SMM_SAVE_STATE_REGISTER_FCW = 256
+ //EFI_SMM_SAVE_STATE_REGISTER_FSW = 257
+ //EFI_SMM_SAVE_STATE_REGISTER_FTW = 258
+ //EFI_SMM_SAVE_STATE_REGISTER_OPCODE = 259
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_EIP = 260
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_CS = 261
+ //EFI_SMM_SAVE_STATE_REGISTER_DATAOFFSET = 262
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_DS = 263
+ //EFI_SMM_SAVE_STATE_REGISTER_MM0 = 264
+ //EFI_SMM_SAVE_STATE_REGISTER_MM1 = 265
+ //EFI_SMM_SAVE_STATE_REGISTER_MM2 = 266
+ //EFI_SMM_SAVE_STATE_REGISTER_MM3 = 267
+ //EFI_SMM_SAVE_STATE_REGISTER_MM4 = 268
+ //EFI_SMM_SAVE_STATE_REGISTER_MM5 = 269
+ //EFI_SMM_SAVE_STATE_REGISTER_MM6 = 270
+ //EFI_SMM_SAVE_STATE_REGISTER_MM7 = 271
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM0 = 272
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM1 = 273
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM2 = 274
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM3 = 275
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM4 = 276
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM5 = 277
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM6 = 278
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM7 = 279
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM8 = 280
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM9 = 281
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM10 = 282
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM11 = 283
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM12 = 284
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM13 = 285
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM14 = 286
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM15 = 287
+ //
+ // Pseudo-Registers
+ //
+ //EFI_SMM_SAVE_STATE_REGISTER_IO = 512
+ //EFI_SMM_SAVE_STATE_REGISTER_LMA = 513
+};
+
+typedef enum {
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT8 = 0,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT16 = 1,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT32 = 2,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT64 = 3
+} CPULIB_SMM_SAVE_STATE_IO_WIDTH;
+
+typedef enum {
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT = 1,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT = 2,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING = 4,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX = 8
+} CPULIB_SMM_SAVE_STATE_IO_TYPE;
+
+typedef struct {
+ UINT64 IoData;
+ UINT16 IoPort;
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH IoWidth;
+ CPULIB_SMM_SAVE_STATE_IO_TYPE IoType;
+} CPULIB_SMM_SAVE_STATE_IO_INFO;
+
+UINT8 IOTypeToEMSSIT[] = {
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING,
+ 0,
+ 0,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_SmmReadSaveState
+//
+// Description: Read SMM Save state from combination of SMM save state and copy.
+// If frame copy exists, use its data instead from actual save state.
+// A different function gets information for floating point and XMM.
+//
+// Input:
+// IN UINT8 *SmmBase - SmmBase of CPU to read Save State.
+// IN UINT8 *SstSaveState - SMM Save state copy for Framework.
+// IN BOOLEAN UseSstSaveState - True if Save state copy exists.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// OUT VOID *Buffer - Read register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPULib_SmmReadSaveState(
+ IN UINT8 *SmmBase,
+ IN UINT8 *SstSaveState,
+ IN BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+)
+{
+ UINT32 Index = 0xffffffff;
+ UINTN Offset;
+
+ if (Register >= 20 && Register <= 46) Index = Register - 20;
+ if (Register >= 51 && Register <= 54) Index = Register - 20 - (51-47);
+
+ if (Index != 0xffffffff) {
+ if (Width > gIntelX64Format[Index].SaveStateWidth) return EFI_INVALID_PARAMETER;
+ switch(Width) {
+ case 1:
+ //Use SMM framework buffer if available, because copy may be updated by Framework driver, and copy will overwrite actual save state at end.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT8*)Buffer = *(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT8*)Buffer = *(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 2:
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT16*)Buffer = *(UINT16*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT16*)Buffer = *(UINT16*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 4:
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT32*)Buffer = *(UINT32*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 8:
+ *(UINT64*)Buffer = *(UINT64*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ //Use copy if available, because copy may be updated by Framework driver, and copy will overwrite actual save state at end. Copy doesn't support upper bits.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ return EFI_SUCCESS;
+ }
+ }
+ if (Register == 4) { //GDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xffd0);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x188);
+ return EFI_SUCCESS;
+ }
+ if (Register == 5) { //IDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xfdd8);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x194);
+ return EFI_SUCCESS;
+ }
+ if (Register == 6) { //LDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xfdd4);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x1c0);
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 513) {
+ UINT16 Efer;
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ Efer = *(UINT16*)(SmmBase + 0xffe0);
+ *(UINT8*)Buffer = (Efer & BIT10) == BIT10 ? 64 : 32;
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 512) {
+ UINT32 IoMisc = *(UINT32*)(SmmBase + 0xffa4);
+ UINT8 Width = 0;
+
+ if (!(IoMisc & 1)) return EFI_NOT_FOUND;
+
+ switch((IoMisc >> 1) & 7) {
+ case 1: Width = 0; break;
+ case 2: Width = 1; break;
+ case 3: Width = 2; break;
+ default: return EFI_NOT_FOUND;
+ };
+
+ //Get the I/O address.
+ switch ((IoMisc >> 4) & 0xF) {
+ case 0:
+ case 1:
+ case 8:
+ case 9:
+ Offset = 0xff5c; //Reg RAX has the value
+ break;
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ Offset = 0xff9c; //IO_MEM_ADDRESS has the value
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoPort = (UINT16)(IoMisc >> 16);
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoWidth = Width;
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoType = IOTypeToEMSSIT[(IoMisc >> 4) & 0xf];
+
+ switch (Width) {
+ case 0:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT8 *)(SmmBase + Offset);
+ break;
+ case 1:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT16 *)(SmmBase + Offset);
+ break;
+ case 2:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT32 *)(SmmBase + Offset);
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED; //Register not supported.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmReadSaveStateFxSave
+//
+// Description: Read SMM Save state for floating point and XMM.
+//
+// Input:
+// IN UINT8 *FxSave - FxSave buffer.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// OUT VOID *Buffer - Read register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuLib_SmmReadSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+)
+{
+ if (Register == 256) { //FCW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)FxSave;
+ return EFI_SUCCESS;
+ }
+ if (Register == 257) { //FSW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 2);
+ return EFI_SUCCESS;
+ }
+ if (Register == 258) { //FTW
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ *(UINT8*)Buffer = *(UINT8*)(FxSave + 4);
+ return EFI_SUCCESS;
+ }
+ if (Register == 259) { //FOP
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 6);
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 260) { //FPU IP
+ if (Width == 4) {
+ MemCpy(Buffer, FxSave + 8, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(Buffer, FxSave + 8, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 261) { //CS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 12);
+ }
+#endif
+
+ if (Register == 262) { //FPU DP (DataOffset)
+ if (Width == 4) {
+ MemCpy(Buffer, FxSave + 16, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(Buffer, FxSave + 16, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 263) { //DS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 20);
+ }
+#endif
+
+ if (Register >= 264 && Register <= 271) { //MM0 - MM7
+ if (Width != 10) return EFI_INVALID_PARAMETER;
+ MemCpy(Buffer, FxSave + 32 + 16 * (Register - 264), 10);
+ return EFI_SUCCESS;
+ }
+ if (Register >= 272 && Register <= 287) { //XMM0 - XMM15
+ if (Width != 16) return EFI_INVALID_PARAMETER;
+ MemCpy(Buffer, FxSave + 160 + 16 * (Register - 272), 16);
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_SmmWriteSaveState
+//
+// Description: Write SMM Save state from combination of SMM save state and copy.
+// If frame copy exists, use its data instead from actual save state.
+// A different function gets information for floating point and XMM.
+//
+// Input:
+// IN UINT8 *SmmBase - SmmBase of CPU to read Save State.
+// IN UINT8 *SstSaveState - SMM Save state copy for Framework.
+// IN BOOLEAN UseSstSaveState - True if Save state copy exists.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// IN VOID *Buffer - Write register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPULib_SmmWriteSaveState(
+ IN OUT UINT8 *SmmBase,
+ IN OUT UINT8 *SstSaveState,
+ IN BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ IN VOID *Buffer
+)
+{
+ UINT32 Index = 0xffffffff;
+
+ if (Register >= 20 && Register <= 46) Index = Register - 20;
+ if (Register >= 51 && Register <= 54) Index = Register - 20 - (51-47); //No tokens assigned 47-50.
+
+ if (Index != 0xffffffff) {
+ if (Width > gIntelX64Format[Index].SaveStateWidth) return EFI_INVALID_PARAMETER;
+ switch(Width) {
+ case 1:
+ *(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT8*)Buffer;
+ //Copy to save state buffer for SMM framework.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT8*)Buffer;
+ return EFI_SUCCESS;
+ case 2:
+ *(UINT16*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT16*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT16*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ case 4:
+ *(UINT32*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT32*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ case 8:
+ *(UINT64*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT64*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ }
+ if (Register == 4) { //GDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xffd0) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe8c) = *(UINT32*)Buffer;
+ //Copy to framework buffer for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x188) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 5) { //IDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xfdd8) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe94) = *(UINT32*)Buffer;
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x194) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 6) { //LDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xfdd4) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe9c) = *(UINT32*)Buffer;
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x1c0) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmWriteSaveStateFxSave
+//
+// Description: Write SMM Save state for floating point and XMM.
+//
+// Input:
+// IN UINT8 *FxSave - FxSave buffer.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// IN VOID *Buffer - Write register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuLib_SmmWriteSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ IN VOID *Buffer
+)
+{
+ if (Register == 256) { //FCW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)FxSave = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 257) { //FSW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 2) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 258) { //FTW
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ *(UINT8*)(FxSave + 4) = *(UINT8*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 259) { //FOP
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 6) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 260) { //FPU IP
+ if (Width == 4) {
+ MemCpy(FxSave + 8, Buffer, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(FxSave + 8, Buffer, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 261) { //CS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 12) = *(UINT16*)Buffer;
+ }
+#endif
+
+ if (Register == 262) { //FPU DP (DataOffset)
+ if (Width == 4) {
+ MemCpy(FxSave + 16, Buffer, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(FxSave + 16, Buffer, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 263) { //DS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 20) = *(UINT16*)Buffer ;
+ }
+#endif
+
+ if (Register >= 264 && Register <= 271) { //MM0 - MM7
+ if (Width != 10) return EFI_INVALID_PARAMETER;
+ MemCpy(FxSave + 32 + 16 * (Register - 264), Buffer, 10);
+ return EFI_SUCCESS;
+ }
+ if (Register >= 272 && Register <= 287) { //XMM0 - XMM15
+ if (Width != 16) return EFI_INVALID_PARAMETER;
+ MemCpy(FxSave + 160 + 16 * (Register - 272), Buffer, 16);
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+static UINT8 CpuIedSig[] = {'I','N','T','E','L',' ','R','S','V','D'};
+
+VOID CPU_SmmMemoryInit(IN SMM_HOB *SmmHob)
+{
+ UINT8 *IedStart;
+ UINT32 IedSize;
+
+ if (!SmmHob->IedStart) return;
+
+ IedStart = (UINT8*)SmmHob->IedStart;
+ IedSize = SmmHob->IedSize;
+
+ MemCpy(IedStart, CpuIedSig, sizeof(CpuIedSig));
+ *(UINT32*)(IedStart + 10) = IedSize;
+
+ *(UINT16*)(IedStart + 14) = 0; //Reserved
+ *(UINT64*)(IedStart + 16) = 0; //Trace memory for Nehalem-EX.
+
+ MemSet(IedStart + 24, 24, 0); //Reserved
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSwSmiTrigger
+//
+// Description: This routine checks to see if the cpu caused an software smi.
+//
+// Input:
+// UINT8 *SmmBase
+// UINT16 SwSmiPort
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSwSmiTrigger(UINT8 *SmmBase, UINT16 SwSmiPort)
+{
+ UINT32 IO_MISC_INFO = *(UINT32*)(SmmBase + 0xffa4);
+ if (!(IO_MISC_INFO & 1)) return FALSE; //For valid data, this should be 1.
+ return (*((UINT16*)&IO_MISC_INFO + 1) == SwSmiPort); //[31:16]
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+
diff --git a/Core/CPU/CpuDxe.c b/Core/CPU/CpuDxe.c
new file mode 100644
index 0000000..9bd4f52
--- /dev/null
+++ b/Core/CPU/CpuDxe.c
@@ -0,0 +1,2096 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.c 21 6/11/15 10:33p Crystallee $
+//
+// $Revision: 21 $
+//
+// $Date: 6/11/15 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.c $
+//
+// 21 6/11/15 10:33p Crystallee
+// [TAG] EIP207854
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Txt test fail with TCG2 module
+// [RootCause] Tokne TCG_SUPPORT was removed.
+// [Solution] Add TCG2Support token.
+//
+// 20 5/24/15 11:36p Davidhsieh
+// [TAG] EIP215675
+// [Category] New Feature
+// [Description] Smm Access Check feautre support
+// [Files] Cpu.sdl, CpuDxe.c, CpuSpSmi.sdl, CpuSpsmi.c
+//
+// 19 8/28/13 6:00a Crystallee
+// [TAG] EIP134339
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] [Sharkbay]Build error after update Haswell Cpu module
+// [RootCause] If token TCG_SUPPORT is disabled, TpmSupport setup data
+// will not define, then cause built error.
+// [Solution] Add token TCG_SUPPORT condition when use TpmSupport setup
+// data.
+//
+// 18 7/23/13 7:45a Crystallee
+// [TAG] EIP128089
+// [Category] Improvement
+// [Description] TXT will be disabled and grayed out in Setup when TPM
+// Support is disabled.
+//
+// 17 3/20/13 2:49a Crystallee
+// [TAG] EIP118478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AES-NI setup item disappear after set ASN-NI to disable.
+// [RootCause] We determine AES support from the ASE support bit in
+// CPUID function 1, but it will change with AES MSR.
+// [Solution] Determine AES support before CPU RC DXE initialize.
+//
+// 16 2/27/13 5:00a Crystallee
+// [TAG] EIP115822
+// [Category] Improvement
+// [Description] Add SMBIOS type7 information for L4 cache if CPU
+// supported
+// And create a token to control this.
+//
+// 15 2/22/13 2:07a Crystallee
+// [TAG] EIP112238
+// [Category] Improvement
+// [Description] Refer Intel BIOS and provide setup items for Intel
+// Haswell RC policy.
+//
+// 14 12/18/12 7:09a Davidhsieh
+// [TAG] EIP93180
+// [Category] Improvement
+// [Description] Do not create timer callback to clear
+// direction flag, clear direction flag operation is in interrupt entry.
+//
+// 13 11/23/12 4:19a Davidhsieh
+// [TAG] None
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Ctdp setup item is not displayed in setup menu
+// [RootCause] The cTDPAvailable value is not initialzied
+// [Solution] Initial cTDPAvailable value
+//
+// 12 11/08/12 6:18a Davidhsieh
+// [TAG] EIP105401
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] CpuSignature and FeatureFlags of MPS table are incorrect
+// [RootCause] Cpu Signature and FeatureFlags in CpuInfo are
+// not initialized
+// [Solution] Initialize Cpu Signature and FeatureFlags in
+// CpuInfo
+//
+// 11 11/07/12 4:36a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] L4 Cache support improve
+//
+// 10 10/17/12 2:20a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Setup items CTDP BIOS, C8, C9 and C10 created
+//
+// 9 10/17/12 1:58a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] L4 cache support
+//
+// 8 9/26/12 10:53a Davidhsieh
+// [TAG] None
+// [Description] Add CPU APIC ID data variable for S3 resume
+//
+// 7 7/10/12 2:48a Davidhsieh
+// [TAG] EIP93180
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The "Event Kernel-Power 137" error event log shows while
+// resumed from HS3/S3 in Windows8 (not-UEFI boot mode)
+// [RootCause] The save MTRRs action is too early, the saved value is
+// differnet from the value in OS
+// [Solution] Move the MTRR save action to AMI_LEGACYBOOT event
+//
+// 6 5/20/12 11:38p Davidhsieh
+// [TAG] EIP89382
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hangs when booting to UEFI Red Hat Linux OS with
+// Network cable plugged in
+// [RootCause] Red Hat Linux OS sets ¡§Direction Flag¡¨ and clears it
+// immediately after few instructions. But before it has been cleared,
+// Timer interrupt has been generated and MemSet () has function has been
+// called inside UEFINetworkStack Timer callback handler. As the
+// "Direction flag" is set ¡§MemSet¡¨ function stores data in reverse
+// direction which results in data corruption.
+// [Solution] Timer Callback function has been created with Higher
+// priority level (TPL_NOTIFY + 14) and "direction flag" has been cleared
+// inside the callback function.
+//
+// 5 5/17/12 9:34p Davidhsieh
+// [TAG] EIP89591
+// [Category] Improvement
+// [Description] Make the CPU wakup buffer locatioin depends on token
+// PMM_EBDA_LOMEM_SIZE
+//
+// 4 3/20/12 3:22a Davidhsieh
+// Create SMBIOS type4 and type7 in AMI CPU module part
+//
+// 3 3/16/12 3:11a Davidhsieh
+// Setup items create for CPU RC policy
+//
+// 2 2/23/12 2:06a Davidhsieh
+// [TAG] EIP72056
+// [Category] Improvement
+// [Description] Change EFI_MP_PROC_CONTEXT to follow Intel CPU driver
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxe.c
+//
+// Description:
+// Installs CPU Architectural Protocol.
+// processor interrupt vector table. The CPU Architectural
+// Protocol enables/disables/get state of interrupts, set
+// memory range cache type, and installs/uninstalls
+// interrupt handlers.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <token.h>
+#include <AmiCspLib.h>
+#include <Protocol\AmiCpuInfo.h>
+#include <Protocol\DxeSmmReadyToLock.h>
+#include "CpuDxe.h"
+#include "PlatformCpuLib.h"
+
+#ifdef CSM_SUPPORT
+#include <Protocol\LegacyBiosExt.h>
+EFI_GUID gAmiLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+#endif
+
+#if AMI_PEI_DEBUG_SUPPORT
+#include "PeiDbgDxeCpuLib.h"
+
+#define AMI_DEBUGGER_CPU_PROTOCOL_GUID \
+ { 0xab21acc3, 0xba33, 0xee2c, 0x66, 0xbc, 0x12, 0x56, 0x77, 0x11, 0x1a, 0xb2 }
+
+typedef struct _AMI_DEBUGGER_CPU_PROTOCOL AMI_DEBUGGER_CPU_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_GET_APTIO_INT_HANDLER) (
+ IN OUT UINT32* InterruptHandlerHaltAddr
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER) (
+ IN IDTEntry_T* IdtEntry,
+ IN UINT32 i
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_SETUP_EXCEPTION_HANDLER) (VOID);
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_IS_DEBUGGER_IRQ_HANDLER) (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+typedef struct _AMI_DEBUGGER_CPU_PROTOCOL {
+ DEBUGGER_GET_APTIO_INT_HANDLER DebuggerGetAptioIntHandler;
+ DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER DebuggerFixUpPEIExceptionHandlers;
+ DEBUGGER_SETUP_EXCEPTION_HANDLER DebuggerSetupExceptionHandler;
+ DEBUGGER_IS_DEBUGGER_IRQ_HANDLER DebuggerIsDebuggerIrqHadler;
+};
+
+
+#endif
+
+#define DELAY_CALCULATE_CPU_PERIOD 200 //uS
+
+#if CPU_MODULE_CREATE_SMBIOS_TABLES == 1
+VOID CpuSmbios();
+#endif
+
+#define AMI_BEFORE_CPU_RC_PROTOCOL_GUID \
+ { 0x1d26adc3, 0xb011, 0xee2c, 0x21, 0x77, 0x89, 0xbb, 0xaa, 0xcc, 0x33, 0x92 }
+
+// Add EFI_MP_PROC_CONTEXT_FROM_RC relavant structures
+typedef struct {
+ UINT32 ApicID;
+ BOOLEAN Enabled;
+ EFI_CPU_DESIGNATION Designation;
+ EFI_MP_HEALTH Health;
+ UINTN PackageNumber;
+ UINTN NumberOfCores;
+ UINTN NumberOfThreads;
+ UINT64 ProcessorPALCompatibilityFlags;
+ UINT64 ProcessorTestMask;
+} EFI_MP_PROC_CONTEXT_FROM_RC;
+
+UINT32 *FindPtrToPrivCpuInfoPkg(
+ IN UINT32 Package
+);
+
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+EFI_GUID gEfiMpServicesProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+EFI_GUID gAmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+EFI_GUID gAmiCpuInfoProtocolGuid = AMI_CPU_INFO_PROTOCOL_GUID;
+EFI_GUID gAmiCpuInfo2ProtocolGuid = AMI_CPU_INFO_2_PROTOCOL_GUID;
+EFI_GUID gAmiBeforeCpuRcProtocolGuid = AMI_BEFORE_CPU_RC_PROTOCOL_GUID;
+EFI_GUID gMpCpuApicIdDataGuid = MP_CPU_APIC_ID_DATA_GUID;
+#if AMI_PEI_DEBUG_SUPPORT
+EFI_GUID gAmiDebuggerCpuProtocolGuid = AMI_DEBUGGER_CPU_PROTOCOL_GUID;
+#endif
+EFI_MP_SERVICES_PROTOCOL *gEfiMpServicesProtocol;
+EFI_MP_PROC_CONTEXT_FROM_RC *gEfiMpProcContext;
+
+UINTN gNumOfCpus;
+UINTN gMaximumNumberOfCPUs;
+UINTN gNumberOfEnabledCPUs;
+UINTN gRendezvousIntNumber;
+UINTN gRendezvousProcLength;
+
+UINT32 gNumOfCpuCores;
+UINT32 gNumOfThreads;
+
+UINT32 gRegEax, gRegEbx, gRegEcx, gRegEdx;
+
+EFI_EVENT gAmiMpEvent;
+VOID *gAmiMpEventRegistration = 0;
+
+EFI_EVENT gSmmFeaEnEvent;
+VOID *gSmmFeaEnReg = 0;
+
+static VOID *gAcpiData;
+static UINT32 gAcpiDataNumEntries;
+
+static CHAR8 gProcObjPath = '\0';
+
+CPUINFO_HOB *gCpuInfoHob;
+AMI_CPU_INFO *gAmiCpuInfo;
+VOID *gSetupHandle;
+CPU_FEATURES gCpuFeatures;
+EFI_PHYSICAL_ADDRESS gTempBuffer;
+BOOLEAN IsFreeMemBelow1MB;
+
+VOID CreatePrivateAmiCpuInfo2();
+UINT32 * GetPtrToPrivateAmiCpuInfo2Entry(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+);
+
+#if AMI_PEI_DEBUG_SUPPORT
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InterruptHandlerHalt
+//
+// Description: Default CPU Exception. Halts CPU.
+//
+// Input:
+// IN EFI_EXCEPTION_TYPE Exception
+// IN EFI_SYSTEM_CONTEXT Context
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InterruptHandlerHalt(EFI_EXCEPTION_TYPE Exception,EFI_SYSTEM_CONTEXT Context)
+{
+ ERROR_CODE(EFI_SOFTWARE_IA32_EXCEPTION | (UINT32)Exception, EFI_ERROR_MAJOR);
+ checkpoint((UINT8)Exception);
+ TRACE((TRACE_DXE_CPU,"ERROR: CPU Exception %X\n",Exception));
+ EFI_DEADLOOP();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerGetAptioInterruptHandlerHalt
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerGetAptioInterruptHandlerHalt(
+ IN OUT UINT32* InterruptHandlerHaltAddr
+)
+{
+
+ *InterruptHandlerHaltAddr = (UINT32)InterruptHandlerHalt;
+ TRACE((TRACE_DXE_CPU,"InterruptHandlerHalt = %X\n",InterruptHandlerHalt));
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerIsItPEIDebugIRQHandlerToHookup
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerFixUpPEIDebuggerExceptionHandlers(
+ IN IDTEntry_T* IdtEntry,
+ IN UINT32 i
+)
+{
+
+ FixUpPEIDebuggerExceptionHandlers((IDTEntry_T*)IdtEntry,i);
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerSetupPEIDebuggerExceptionHandlers
+//
+// Description:
+//
+// Input:
+//
+//
+// Output:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerSetupPEIDebuggerExceptionHandlers(VOID)
+{
+
+ SetupPEIDebuggerExceptionHandlers( );
+ return EFI_SUCCESS;
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerIsItPEIDebugIRQHandlerToHookup
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerIsItPEIDebugIRQHandlerToHookup(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
+{
+
+ IsItPEIDebugIRQHandlerToHookup(InterruptType,InterruptHandler);
+ return EFI_SUCCESS;
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateTimerPeriod
+//
+// Description: Calculate CPU time period.
+//
+// Input: VOID
+//
+// Output:
+// UINT64 Timer Period
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT64 CalculateTimerPeriod()
+{
+ UINT64 Timer1;
+ UINT64 Timer2;
+
+ EFI_TPL OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ Timer1 = ReadRtdsc();
+
+ pBS->Stall(DELAY_CALCULATE_CPU_PERIOD);
+
+ Timer2 = ReadRtdsc();
+
+ pBS->RestoreTPL(OldTpl);
+
+ return Div64(DELAY_CALCULATE_CPU_PERIOD * (UINT64)1000000000, (UINT32)(Timer2-Timer1),NULL); //50us * 10E15 femtosec;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuInfo
+//
+// Description: Protocol function to get Cpu Info.
+//
+// Input:
+// IN AMI_CPU_INFO_PROTOCOL *This
+// IN UINTN Cpu
+// OUT AMI_CPU_INFO **Info
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetCpuInfo(
+ IN AMI_CPU_INFO_PROTOCOL *This,
+ IN UINTN Cpu,
+ OUT AMI_CPU_INFO **Info
+)
+{
+ if (Cpu >= gNumOfCpus) return EFI_INVALID_PARAMETER;
+ *Info = &gAmiCpuInfo[Cpu];
+ return EFI_SUCCESS;
+}
+
+AMI_CPU_INFO_PROTOCOL gAmiCpuInfoProtocol = {GetCpuInfo};
+
+static CACHE_DESCRIPTOR_INFO gZeroCacheDesc = {0, 0, 0, 0, 0};
+
+typedef struct {
+ UINT32 NumCores; //Number of cores in Package.
+ UINT32 NumEntries; //Each cache descriptor should have same number of entries, max of 4.
+ AMI_CPU_INFO_2_CACHE_DESCR PkgCacheDesc[4]; //Total of the cores
+ AMI_CPU_INFO_2_CACHE_DESCR CoreCacheDesc[4]; //Internal implementation assumes symmetry among cores.
+ //If this every changes, internal implementation will be updated.
+} PKG_CACHE_DESCR;
+
+static PKG_CACHE_DESCR *gPkgCacheDesc; //Array of Package Cache Descriptions.
+
+
+typedef struct {
+ UINT32 CacheType:5;
+ UINT32 CacheLevel:3;
+ UINT32 NotUsed:24;
+} CPUID4_EAX_CACHE_INFO;
+
+typedef struct {
+ UINT32 LineSize:12;
+ UINT32 Partitions:10;
+ UINT32 Ways:10;
+} CPUID4_EBX_CACHE_INFO;
+
+#define MAX_NUM_CACHE_DESC 8
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoPkg
+//
+// Description: Pointer to internal Package information.
+//
+// Input:
+// IN UINT32 PkgPtr -- Internal package information.
+//
+// Output: UINT32 * -- Internal Core information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 *FindPtrToPrivCpuInfoPkg(
+ IN UINT32 Package
+)
+{
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 i;
+
+ if (Package >= *p) return (UINT32*)-1; //Package does not exist.
+ p++; //now p = Num cores of package 0.
+
+ //Skip entries for previous packages.
+ for (i = 0; i < Package; ++i) {
+ UINT32 NumCores = *p++; //p = now number of threads
+ UINT32 j;
+ for (j = 0; j < NumCores; ++j) {
+ UINT32 NumThreads = *p++;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ }
+ }
+ return p;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoCore
+//
+// Description: Pointer to internal Core information.
+//
+// Input:
+// IN UINT32* PkgPtr -- Internal package information.
+// IN UINT32 Core
+//
+// Output: UINT32 * -- Internal Core information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 *FindPtrToPrivCpuInfoCore(
+ IN UINT32 *PkgPtr,
+ IN UINT32 Core
+)
+{
+ UINT32 *p = PkgPtr;
+ UINT32 NumCores = *p++;
+ UINT32 i;
+ if (Core >= NumCores) return (UINT32*)-1; //Core does not exist.
+
+ //Skip previous cores.
+ for (i = 0; i < Core; ++i) {
+ UINT32 NumThreads = *p++;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ }
+ return p;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoThread
+//
+// Description: Pointer to internal Core information.
+//
+// Input:
+// IN UINT32* CorePtr -- Internal core information.
+// IN UINT32 Thread
+//
+// Output: UINT32 * -- Internal thread information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 *FindPtrToPrivCpuInfoThread(
+ IN UINT32 *CorePtr,
+ IN UINT32 Thread
+)
+{
+ UINT32 *p = CorePtr;
+ UINT32 NumThreads = *p++;
+ if (Thread >= NumThreads) return (UINT32*)-1; //Thread does not exist.
+ p += Thread * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ return p;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetBoardSocketNumber
+//
+// Description: Get socket number from Apic ID.
+//
+// Input:
+// IN UINT32 ApicId
+//
+// Output: UINT32 - Physical Socket Id
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetBoardSocketNumber(IN UINT32 ApicId)
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 MaxThreadsPackage;
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ MaxThreadsPackage = (UINT8)(RegEbx >> 16);
+
+ return ApicId / MaxThreadsPackage;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumPackages
+//
+// Description: Get the number of packages populated and sockets.
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT UINT32 *NumPopulatedPackages
+// OUT UINT32 *NumBoardSockets OPTIONAL
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumPackages(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT UINT32 *NumPopulatedPackages,
+ OUT UINT32 *NumBoardSockets OPTIONAL
+)
+{
+ //First entry after protocol functions is number of discovered packages.
+ /*UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+
+ *NumPopulatedPackages = *p;
+ //NUMBER_CPU_SOCKETS must be ported if more than 1 socket.
+ ASSERT(*NumPopulatedPackages <= NUMBER_CPU_SOCKETS);
+ if (NumBoardSockets) {
+ *NumBoardSockets = NUMBER_CPU_SOCKETS;
+
+ //In case of porting error, Board sockets can never be less than Populated packages.
+ if (*NumPopulatedPackages > *NumBoardSockets) *NumBoardSockets = *NumPopulatedPackages;
+ }*/
+
+ if(NumPopulatedPackages == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *NumPopulatedPackages = 1;
+
+ if (NumBoardSockets)
+ *NumBoardSockets = 1;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumCoresThreads
+//
+// Description: Get the number of Cores
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This,
+// IN UINT32 Package
+// OUT UINT32 *NumEnabledCores
+// OUT UINT32 *NumEnabledThreads - This value is total for package.
+// OUT UINT32 *NumDisabledCores OPTIONAL -- Flag must be set in Protocol.
+// OUT UINT32 *NumEnabledThreads OPTIONAL -- Flag must be set in Protocol.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumCoresThreads(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ OUT UINT32 *NumEnabledCores,
+ OUT UINT32 *NumEnabledThreads,
+ OUT UINT32 *NumDisabledCores OPTIONAL,
+ OUT UINT32 *NumDisabledThreads OPTIONAL
+)
+{
+ UINT32 *p = FindPtrToPrivCpuInfoPkg(Package);
+ UINT32 TotNumCores;
+ UINT32 TotNumThreads = 0;
+ UINT32 i;
+
+ if (NumEnabledCores == NULL || NumEnabledThreads == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ //After package is number of cores.
+ TotNumCores = *p++;
+ for (i = 0; i < TotNumCores; ++i) {
+ UINT32 NumThreads = *p++; //After core is Number of Threads
+ TotNumThreads += NumThreads;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA; //APIC ID and CPU NUM;
+ }
+
+ *NumEnabledCores = TotNumCores;
+ *NumEnabledThreads = TotNumThreads;
+
+ if (NumDisabledCores) *NumDisabledCores = 0; //Flag not set in Protocol.
+ if (NumDisabledThreads) *NumDisabledThreads = 0; //Flag not set in Protocol.*/
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumThreads
+//
+// Description: Get the number of Threads
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package
+// IN UINT32 Core
+// OUT UINT32 *NumEnabledThreads
+// OUT UINT32 *NumDisabledThreads OPTIONAL -- Flag must be set if valid
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumThreads(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ OUT UINT32 *NumEnabledThreads,
+ OUT UINT32 *NumDisabledThreads OPTIONAL
+)
+{
+ UINT32 *p = FindPtrToPrivCpuInfoPkg(Package);
+
+ if (NumEnabledThreads == NULL) return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ p = FindPtrToPrivCpuInfoCore(p, Core);
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ *NumEnabledThreads = *p;
+ if (NumDisabledThreads) *NumDisabledThreads = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetSbsp
+//
+// Description: Get SBSP
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT UINT32 *Package
+// OUT UINT32 *Core
+// OUT UINT32 *Thread
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetSbsp(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT UINT32 *Package,
+ OUT UINT32 *Core,
+ OUT UINT32 *Thread
+)
+{
+ //Desktop system, it must be package0, core0, thread0
+ if (Package == NULL || Core == NULL || Thread == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *Package = 0;
+ *Core = 0;
+ *Thread = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetApicInfo
+//
+// Description: Get Apic Number and Version
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+// OUT UINT32 *ApicId
+// OUT UINT32 *ApicVer OPTIONAL
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetApicInfo(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread,
+ OUT UINT32 *ApicId,
+ OUT UINT32 *ApicVer OPTIONAL
+)
+{
+ UINT32 *p = GetPtrToPrivateAmiCpuInfo2Entry(
+ Package, Core, Thread);
+ UINT32 CpuNum;
+
+ if (ApicId == NULL) return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ //p points to 32-bit APIC ID and 32-bit CPU Num for internal structures.
+
+ *ApicId = *p++;
+
+ if (ApicVer) {
+ CpuNum = *p;
+ *ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetAcpiInfo
+//
+// Description: Get Cpu ACPI information.
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT VOID **AcpiData - ACPI Data
+// OUT UINT32 *NumEntries - Number of Entries in data.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetAcpiInfo(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT VOID **AcpiData,
+ OUT UINT32 *NumEntries
+)
+{
+ if (AcpiData == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *AcpiData = gAcpiData;
+ *NumEntries = gAcpiDataNumEntries;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetPackageCacheDescr
+//
+// Description: Get the package Cache Information
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package - Socket number. Intenal socket number (continous)
+// OUT AMI_CPU_INFO_2_CACHE_DESCR **Description - Updates pointer to pointer with pointer to Cache information.
+// OUT UINT32 *NumEntries - Number of AMI_CPU_INFO_2_CACHE_DESCR Entries.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPackageCacheDescr(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ OUT AMI_CPU_INFO_2_CACHE_DESCR **Description,
+ OUT UINT32 *NumEntries
+)
+{
+ PKG_CACHE_DESCR *PkgCacheDesc;
+
+ if (Package >= NumberOfCpuSocketsPopulated()) return EFI_INVALID_PARAMETER;
+
+ if (Description == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PkgCacheDesc = &gPkgCacheDesc[Package];
+ *Description = &PkgCacheDesc->PkgCacheDesc[0];
+ *NumEntries = PkgCacheDesc->NumEntries;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCoreCacheDescr
+//
+// Description: Get the Core Cache Information
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package - Socket number. Internal socket number (continous)
+// IN UINT32 Core - Core number. Internal core number (continous)
+// OUT AMI_CPU_INFO_2_CACHE_DESCR **Description - Updates pointer to pointer with pointer to Cache information.
+// OUT UINT32 *NumEntries - Number of AMI_CPU_INFO_2_CACHE_DESCR Entries.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetCoreCacheDescr(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ OUT AMI_CPU_INFO_2_CACHE_DESCR **Description,
+ OUT UINT32 *NumEntries
+)
+{
+ PKG_CACHE_DESCR *PkgCacheDesc;
+
+ if (Package >= NumberOfCpuSocketsPopulated()) return EFI_INVALID_PARAMETER;
+
+ if (Description == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PkgCacheDesc = &gPkgCacheDesc[Package];
+
+ if (Core >= PkgCacheDesc->NumCores) return EFI_INVALID_PARAMETER;
+
+ *Description = &PkgCacheDesc->CoreCacheDesc[0];
+ *NumEntries = PkgCacheDesc->NumEntries;
+ return EFI_SUCCESS;
+}
+
+PRIVATE_AMI_CPU_INFO_2_PROTOCOL PrivateAmiCpuInfo2Init = {
+ {
+ 1, //ProtocolVer
+ 0, //Flags
+ GetNumPackages,
+ GetNumCoresThreads,
+ GetNumThreads,
+ GetSbsp,
+ GetApicInfo,
+ GetAcpiInfo,
+ GetPackageCacheDescr,
+ GetCoreCacheDescr
+ }
+ //Additional information will allocated.
+};
+
+PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SizeOfPrivateAmiCpuInfo2
+//
+// Description: Size of Private Ami Cpu Info 2 structure to be allocated.
+//
+// Input: VOID
+//
+// Output: UINT32 -- Size
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 SizeOfPrivateAmiCpuInfo2()
+{
+ //See PRIVATE_AMI_CPU_INFO_2_PROTOCOL defintion for comments on internal CPU information.
+
+ UINT32 Size = sizeof(AMI_CPU_INFO_2_PROTOCOL);
+ UINT32 NumSockets = 1;
+ UINT32 CpuNum = 0;
+ UINT32 j;
+
+ Size += sizeof(UINT32); //Number of populated sockets entry.
+ Size += sizeof(UINT32); //Number of cores for socket;
+ for (j = 0; j < gNumOfCpuCores; ++j) {
+ Size += sizeof(UINT32); //Number of thread per core.
+ Size += gNumOfThreads * sizeof(UINT32) * PRIVATE_INFO_NUM_OF_CPU_DATA; //APIC ID and CPU NUM;
+ CpuNum += gNumOfThreads;
+ ASSERT(CpuNum <= gNumOfCpus);
+ }
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillPrivateAmiCpuInfo2
+//
+// Description: Fill CPU information in Private Ami Cpu Info structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillPrivateAmiCpuInfo2()
+{
+ //See PRIVATE_AMI_CPU_INFO_2_PROTOCOL defintion for comments on internal CPU information.
+
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 NumSockets = 1;
+ UINT32 CpuNum = 0;
+ UINT32 i;
+ UINT32 j;
+ UINT32 k;
+
+ *gPrivateAmiCpuInfo2 = PrivateAmiCpuInfo2Init;
+ *p++ = NumSockets;
+ for (i = 0; i < NumSockets; ++i) {
+ *p++ = gNumOfCpuCores;
+ for (j = 0; j < gNumOfCpuCores; ++j) {
+ *p++ = gNumOfThreads;
+ for (k = 0; k < gNumOfThreads; ++k) {
+ *p++ = gEfiMpProcContext[CpuNum].ApicID;
+ *p++ = CpuNum;
+ ++CpuNum;
+ ASSERT(CpuNum <= gNumOfCpus);
+ }
+ }
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetPtrToPrivateAmiCpuInfo2Entry
+//
+// Description: Get pointer to APIC/Cpu Num
+//
+// Input:
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+//
+// Output: UINT32 *
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 * GetPtrToPrivateAmiCpuInfo2Entry(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+)
+{
+ UINT32 *p;
+
+ p = FindPtrToPrivCpuInfoPkg(Package);
+ if (p == (UINT32*) -1) return (UINT32*)-1; //Package does not exist.
+
+ p = FindPtrToPrivCpuInfoCore(p, Core);
+ if (p == (UINT32*) -1) return (UINT32*)-1; //Core does not exist.
+
+ p = FindPtrToPrivCpuInfoThread(p, Thread);
+ return p;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCpuPkgCoreThrdByNum
+//
+// Description: Get CPU Package/Core/Thread by CPU Number. Number sequencial to APIC ID.
+//
+// Input:
+// IN UINT32 CpuNum
+// OUT UINT32 *Package
+// OUT UINT32 *Core
+// OUT UINT32 *Thread
+//
+// Output: BOOLEAN -- If found, return TRUE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN GetCpuPkgCoreThrdByNum(
+ IN UINT32 CpuNum,
+ OUT UINT32 *Package,
+ OUT UINT32 *Core,
+ OUT UINT32 *Thread
+)
+{
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 NumPkgs = *p++;
+ UINT32 Pkg;
+
+ for (Pkg = 0; Pkg < NumPkgs; ++Pkg) {
+ UINT32 NumCores = *p++;
+ UINT32 Cor;
+ for (Cor = 0; Cor < NumCores; ++Cor) {
+ UINT32 NumThrds = *p++;
+ UINT32 Thrd;
+ for (Thrd = 0; Thrd < NumThrds; ++Thrd) {
+ ++p; //Skip ApicId;
+ if (*p++ == CpuNum) {
+ *Package = Pkg;
+ *Core = Cor;
+ *Thread = Thrd;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillAcpiData
+//
+// Description: Fill ACPI Data structure
+//
+// Input:
+// IN ACPI_PROCESSOR_INFO *AcpiProcData
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+// IN BOOLEAN Bsp
+//
+// Output: BOOLEAN -- If filled, return TRUE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN FillAcpiData(
+ OUT ACPI_PROCESSOR_INFO *AcpiProcData,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread,
+ IN BOOLEAN Bsp
+)
+{
+ UINT32 ApicId;
+ UINT32 CpuNum;
+ UINT32 CpuSignature, CpuIdEBX, CpuIdECX, FeatureFlags;
+
+ static UINT32 ProcId = 1;
+
+ UINT32 *ptr = GetPtrToPrivateAmiCpuInfo2Entry(Package, Core, Thread);
+ if (ptr == (UINT32*) -1) return FALSE;
+ //ptr points to 32-bit APIC ID and 32-bit CPU Num for internal structures.
+
+ ApicId = *ptr++;
+ CpuNum = *ptr;
+ CPULib_CpuID(1, &CpuSignature, &CpuIdEBX, &CpuIdECX, &FeatureFlags);
+
+ AcpiProcData->Type = ACPI_PROCESSOR_INFO_TYPE; //0
+ AcpiProcData->Length = sizeof(ACPI_PROCESSOR_INFO);
+ AcpiProcData->Enable = 1;
+ AcpiProcData->Bsp = Bsp;
+ AcpiProcData->Package = Package;
+ AcpiProcData->Core = Core;
+ AcpiProcData->Thread = Thread;
+ AcpiProcData->ApicId = ApicId; //LAPIC number for processor.
+ //AcpiProcData->ApicVer = gCpuInfoHob->Cpuinfo[CpuNum].ApicVer;
+ AcpiProcData->ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ AcpiProcData->CpuSignature = CpuSignature;
+ AcpiProcData->FeatureFlags = FeatureFlags & (BIT0 | BIT7 | BIT8 | BIT9);
+ AcpiProcData->ProcId = ProcId; //ASL processor object ID.
+ //AcpiProcData->ProcObjPath = (EFI_PHYSICAL_ADDRESS)(UINTN)&gProcObjPath; //ASL processor object ID.
+ AcpiProcData->LocalApicType = FALSE; //All processors will either be xAPIC or x2APIC Mode not mixed.
+ ++ProcId;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AddLocalApicCoreEntries
+//
+// Description: Create Private Ami Cpu Info2 Acpi Data.
+//
+// Input:
+// IN UINT32 Package - Processor package
+// IN UINT32 Thread - Processor thread (usually either 0 or 1 for HT)
+//
+// Output: BOOLEAN - TRUE if any entries added.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN AddLocalApicCoreEntries(
+ IN UINT32 Package,
+ IN UINT32 Thread,
+ IN BOOLEAN Bsp,
+ IN UINT32 BspCore
+){
+ UINT32 NumEnabledCores;
+ UINT32 NumEnabledThreads;
+ UINT32 Core;
+ BOOLEAN ValidEntry;
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+ ACPI_PROCESSOR_INFO *AcpiProcData = (ACPI_PROCESSOR_INFO *)gAcpiData;
+ static UINT32 Entry = 0;
+
+ AmiCpu2Info->GetNumCoresThreads(AmiCpu2Info, Package, &NumEnabledCores, &NumEnabledThreads, NULL, NULL);
+ NumEnabledThreads = NumEnabledThreads / NumEnabledCores;
+
+ if (Thread >= NumEnabledThreads) return FALSE; //Different packages could have different numbers of threads;
+
+ ValidEntry = FillAcpiData(
+ &AcpiProcData[Entry],
+ Package,
+ BspCore,
+ Thread,
+ Bsp && Thread == 0
+ );
+ if (ValidEntry) ++Entry;
+
+ for (Core = 0; Core < NumEnabledCores; ++Core) {
+ if (Core == BspCore) continue;
+ ValidEntry = FillAcpiData(
+ &AcpiProcData[Entry],
+ Package,
+ Core,
+ Thread,
+ FALSE
+ );
+ if (ValidEntry) ++Entry;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateAcpiData
+//
+// Description: Create Private Ami Cpu Info2 Acpi Data.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateAcpiData()
+{
+ EFI_STATUS Status;
+ UINT32 Package;
+ UINT32 Thread;
+ UINT32 BspPackage;
+ UINT32 BspCore;
+ UINT32 BspThread;
+ UINT32 MaxPackages;
+ BOOLEAN ProcessedEntries;
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+
+ gAcpiDataNumEntries = (UINT32)gNumOfCpus;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(ACPI_PROCESSOR_INFO) * gNumOfCpus, &gAcpiData);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = AmiCpu2Info->GetSbsp(
+ AmiCpu2Info,
+ &BspPackage,
+ &BspCore,
+ &BspThread
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = AmiCpu2Info->GetNumPackages(AmiCpu2Info, &MaxPackages, NULL);
+ ASSERT_EFI_ERROR(Status);
+ Thread = 0; //Thread count for a core.
+
+ do { //Thread
+ ProcessedEntries = FALSE;
+
+ //Bsp is always first entry.
+ if (AddLocalApicCoreEntries(BspPackage, Thread, TRUE, BspCore))
+ ProcessedEntries = TRUE;
+
+ for (Package = 0; Package < MaxPackages; ++Package) {
+ if (Package == BspPackage) continue;
+ if (AddLocalApicCoreEntries(Package, Thread, FALSE, BspCore))
+ ProcessedEntries = TRUE;
+ }
+ ++Thread;
+ } while (ProcessedEntries); //No more threads
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCacheSharedThreads
+//
+// Description: Return number of shared threads for a Information.
+//
+// Input: IN UINT8 Level - Cache level
+//
+// Output: UINT8 - Number of shared threads.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 GetCacheSharedThreads(IN UINT8 Level)
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT32 i = 0;
+
+ for(;;) {
+ RegEcx = i;
+ CPULib_CpuID(4, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if ((RegEax & 0x1f) == 0) break;
+ if (((RegEax >> 5) & 7) == Level) return 1 + ((RegEax >> 14)& 0xfff);
+ ++i;
+ }
+ return 0;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateCacheData
+//
+// Description: Get Cache information.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateCacheData()
+{
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+ UINT32 NumPackages;
+ UINT32 Package;
+ UINT32 CpuNum;
+ EFI_STATUS Status;
+
+ BOOLEAN IsLxSharedByPackage[5];
+
+ //Assume between CPUs on the board, similar cache sharing. Only like CPUs can power the board.
+ IsLxSharedByPackage[1] = GetCacheSharedThreads(1) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[2] = GetCacheSharedThreads(2) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[3] = GetCacheSharedThreads(3) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[4] = GetCacheSharedThreads(4) > 2 ? TRUE: FALSE;
+
+ Status = AmiCpu2Info->GetNumPackages(AmiCpu2Info, &NumPackages, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(PKG_CACHE_DESCR) * NumPackages, &gPkgCacheDesc);
+ ASSERT_EFI_ERROR(Status);
+
+ MemSet(gPkgCacheDesc, sizeof(PKG_CACHE_DESCR) * NumPackages, 0);
+
+ //Assume symmetry between the cores in a package. This never likely to change.
+ for(Package = 0, CpuNum = 0; CpuNum < gNumOfCpus; ++Package) {
+ AMI_CPU_INFO *AmiCpuInfo = &gAmiCpuInfo[CpuNum];
+ PKG_CACHE_DESCR *PkgDesc = &gPkgCacheDesc[Package];
+ CACHE_DESCRIPTOR_INFO *CacheInfo = AmiCpuInfo->CacheInfo;
+ UINT32 NumCores = AmiCpuInfo->NumCores;
+ UINT32 Entry = 0;
+
+ ASSERT (Package < NumPackages);
+
+ PkgDesc->NumCores = NumCores;
+
+ while(CacheInfo->Desc != 0) {
+ AMI_CPU_INFO_2_CACHE_DESCR *PkgCacheDesc = &PkgDesc->PkgCacheDesc[Entry];
+ AMI_CPU_INFO_2_CACHE_DESCR *CoreCacheDesc = &PkgDesc->CoreCacheDesc[Entry];
+
+ ASSERT(Entry < MAX_NUM_CACHE_DESC);
+ ASSERT(CacheInfo->Level < 5);
+
+ CoreCacheDesc->LengthDesc = sizeof(AMI_CPU_INFO_2_CACHE_DESCR);
+ CoreCacheDesc->Level = CacheInfo->Level;
+ CoreCacheDesc->Type = CacheInfo->Type;
+ CoreCacheDesc->Size = CacheInfo->Size;
+ CoreCacheDesc->Associativity = CacheInfo->Associativity;
+ CoreCacheDesc->Shared = IsLxSharedByPackage[CacheInfo->Level] + 1;
+
+ if (CoreCacheDesc->Type == 3) {
+ CoreCacheDesc->Type = 2; //Translate type from AMI CPU INFO 1 to AMI CPU INFO 2.
+ }
+
+ MemCpy(PkgCacheDesc, CoreCacheDesc, sizeof(AMI_CPU_INFO_2_CACHE_DESCR));
+
+ PkgCacheDesc->Size *= !IsLxSharedByPackage[CacheInfo->Level] ? NumCores : 1;
+
+ ++Entry;
+ ++CacheInfo;
+ }
+ CpuNum += NumCores * (AmiCpuInfo->NumHts ? 2 : 1) ;
+ PkgDesc->NumEntries = Entry;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreatePrivateAmiCpuInfo2
+//
+// Description: Create Private Ami Cpu Info2 structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreatePrivateAmiCpuInfo2()
+{
+ EFI_STATUS Status;
+
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ SizeOfPrivateAmiCpuInfo2(),
+ &gPrivateAmiCpuInfo2
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ FillPrivateAmiCpuInfo2();
+
+ CreateAcpiData();
+
+ CreateCacheData();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillCacheDesc
+//
+// Description: Update cache information with CPUID 4.
+//
+// Input:
+// CACHE_DESCRIPTOR_INFO * CacheInfo - Array to be filled of cache info structures.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillCacheDesc(CACHE_DESCRIPTOR_INFO * CacheInfo)
+{
+ CPUID4_EAX_CACHE_INFO EaxInfo;
+ CPUID4_EBX_CACHE_INFO EbxInfo;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT32 CacheCount;
+
+ for (CacheCount = 0; CacheCount < (MAX_NUM_CACHE_DESC - 1); ++CacheCount) {
+ RegEcx = CacheCount;
+ CPULib_CpuID(4, (UINT32*)&EaxInfo, (UINT32*)&EbxInfo, &RegEcx, &RegEdx);
+ if (EaxInfo.CacheType == 0) break; //No more cache.
+
+ CacheInfo[CacheCount].Desc = 0xff; //Unused.
+ CacheInfo[CacheCount].Level = EaxInfo.CacheLevel;
+ switch (EaxInfo.CacheType) {
+ case 1: CacheInfo[CacheCount].Type = 0; break;
+ case 2: CacheInfo[CacheCount].Type = 1; break;
+ case 3: CacheInfo[CacheCount].Type = 3; break;
+ }
+
+ CacheInfo[CacheCount].Size =
+ (EbxInfo.Ways + 1) * (EbxInfo.Partitions + 1) * (EbxInfo.LineSize + 1) * (RegEcx + 1) /
+ 1024;
+ CacheInfo[CacheCount].Associativity = EbxInfo.Ways + 1;
+ }
+ CacheInfo[CacheCount] = gZeroCacheDesc;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreatePrivateAmiCpuInfo1
+//
+// Description: Create Private Ami Cpu Info1 structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreatePrivateAmiCpuInfo1()
+{
+ EFI_STATUS Status;
+ AMI_CPU_INFO *AmiCpuInfo;
+ UINT64 MicroCodeVersion;
+ UINT32 CpuSignature;
+ UINT32 i;
+ UINT32 Bclk;
+ UINT32 RegEAX, RegEBX, RegECX, RegEDX;
+ UINT32 FeatureEcx, FeatureEdx;
+ UINT32 ExtFeatureEdx;
+ CHAR8 *BrandString;
+ CHAR8 *BrandString1;
+ UINT64 TimerPeriod;
+ UINT8 *pos1;
+ BOOLEAN Ht0 = IsHt0(); //True, if not hyper-threaded CPU.
+ //AMI_CPU_INFO *AmiCpuInfo = &gAmiCpuInfo[Cpu];
+
+
+ //Allocate memory for AMI_CPU_INFO. This will be filled by CPU initialization.
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(AMI_CPU_INFO) * gNumOfCpus,
+ &gAmiCpuInfo
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //Get Cpu Signature
+ CpuSignature = GetCpuSignature();
+
+ //Use 100 for bclk for Sandy Bridge and Ivy Bridge
+ Bclk = 100;
+
+ //Allocate memory for Brand string
+ Status = pBS->AllocatePool(EfiBootServicesData, 49, &BrandString);
+ ASSERT_EFI_ERROR(Status);
+ BrandString1 = BrandString;
+ //Get Brand string
+ CPULib_CpuID(0x80000002, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+
+ CPULib_CpuID(0x80000003, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+
+ CPULib_CpuID(0x80000004, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+ *BrandString = '\0';
+
+ BrandString = BrandString1;
+
+ //Using CPUID to get related feature
+ CPULib_CpuID(1, &RegEAX, &RegEBX, &FeatureEcx, &FeatureEdx);
+ CPULib_CpuID(0x80000001, &RegEAX, &RegEBX, &RegECX, &ExtFeatureEdx);
+
+ //Get loaded Microcode version, MSR 0x8b [EDX] = Microcode version
+ MicroCodeVersion = ReadMsr(0x8b);
+ MicroCodeVersion = *((UINT32*)&MicroCodeVersion + 1); //ignore upper 32-bits.
+
+ TimerPeriod = CalculateTimerPeriod(); //10^-15 s.
+
+ for(i = 0; i < gNumOfCpus; i++ )
+ {
+
+ AmiCpuInfo = &gAmiCpuInfo[i];
+
+
+ Status = pBS->AllocatePool(EfiBootServicesData, MAX_NUM_CACHE_DESC * sizeof(CACHE_DESCRIPTOR_INFO), &AmiCpuInfo->CacheInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ FillCacheDesc(AmiCpuInfo->CacheInfo); //Get Cache Information.
+ //Remove leading spaces. After removing leading spaces, the Brand String can not be
+ //freed. However, it should never be freed.
+
+ AmiCpuInfo->BrandString = BrandString;
+
+ while (*AmiCpuInfo->BrandString == ' ') ++AmiCpuInfo->BrandString;
+
+ //Remove extra spaces in middle.
+ pos1 = AmiCpuInfo->BrandString;
+
+ for(;;) {
+ UINT8 *pos2;
+ UINT8 *pos3;
+ while (*pos1 != ' ' && *pos1 != '\0') ++pos1; //Find next space.
+ if (*pos1 == '\0') break; //If found terminator, break.
+ if (*++pos1 != ' ') continue; //If not second space, continue scanning.
+ pos2 = pos1; //Found 2 spaces.
+ while(*++pos2 == ' '); //Skip spaces.
+ pos3 = pos1;
+ while(*pos2 != '\0') *pos3++ = *pos2++; //copy string
+ *pos3++ = '\0'; //Add terminator.
+ }
+
+ AmiCpuInfo->Version = CpuSignature;
+ AmiCpuInfo->X64Supported = (ExtFeatureEdx >> 29) & 1;
+ AmiCpuInfo->Ht0 = Ht0;
+ AmiCpuInfo->Features = Shl64(FeatureEcx, 32) + FeatureEdx;
+ AmiCpuInfo->NumCores = gNumOfCpuCores;
+ AmiCpuInfo->NumHts = IsHtEnabled() * 2; //Either 2 or 0.
+ AmiCpuInfo->FSBFreq = Bclk;
+ AmiCpuInfo->Voltage = 0; //Voltage is variable, and no information os available.
+ AmiCpuInfo->MicroCodeVers = (UINT32)MicroCodeVersion;
+ AmiCpuInfo->IntendedFreq = ((UINT32)ReadMsr(0x198) >> 8) * Bclk;
+ AmiCpuInfo->ActualFreq = 1000000000/(UINT32)TimerPeriod;
+ }
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GlobalDataInitialize
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle -- Handle assigned to this driver.
+// IN EFI_SYSTEM_TABLE *SystemTable -- Efi System table.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GlobalDataInitialize(VOID)
+{
+
+ EFI_STATUS Status;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ EFI_MP_PROC_CONTEXT_FROM_RC *ptr;
+ UINT32 i;
+ UINTN BufferSize;
+
+ gNumOfCpuCores = ((UINT32)(MsrData >> 16 & 0xff));
+ //Locate MP services protocol provided by CPU RC
+ Status = pBS->LocateProtocol(&gEfiMpServicesProtocolGuid, NULL, &gEfiMpServicesProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ if (!EFI_ERROR(Status)){
+ //Get number of Cpus on system
+ gEfiMpServicesProtocol->GetGeneralMPInfo(
+ gEfiMpServicesProtocol,
+ &gNumOfCpus,
+ &gMaximumNumberOfCPUs,
+ &gNumberOfEnabledCPUs,
+ &gRendezvousIntNumber,
+ &gRendezvousProcLength
+ );
+
+ }else{
+ return Status;
+ }
+
+ gNumOfThreads = (UINT32)(gNumOfCpus / gNumOfCpuCores);
+ //TRACE((-1, "Cpu MP service cpus = %x cores %x threads %x\n", gNumOfCpus, gNumOfCpuCores, gNumOfThreads));
+
+ //Get MP processor context of each CPU
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_MP_PROC_CONTEXT_FROM_RC) * gNumOfCpus,
+ &gEfiMpProcContext
+ );
+
+ ptr = gEfiMpProcContext;
+ BufferSize = sizeof(EFI_MP_PROC_CONTEXT_FROM_RC);
+ for(i = 0; i < gNumOfCpus; i++ , ptr++)
+ {
+ gEfiMpServicesProtocol->GetProcessorContext(
+ gEfiMpServicesProtocol,
+ i,
+ &BufferSize,
+ ptr
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareToBoot
+//
+// Description: Handler executed before OS.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PrepareToBoot(IN EFI_EVENT Event, IN VOID *Context)
+{
+ //Trigger SWSMI to save CPU fixed & varible MTRRs
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_SAVE_MSR);
+
+}
+#if CPU_SETUP_SET_BOOT_RATIO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSetBootRatio
+//
+// Description: Adjust CPU boot ratio base on setup item
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CpuSetBootRatio(VOID)
+{
+
+ UINT8 MaxRatio = Shr64(ReadMsr(MSR_PLATFORM_INFO),8) & 0xff;
+ UINT8 MinRatio = Shr64(ReadMsr(MSR_PLATFORM_INFO),40) & 0xff;
+ UINT8 DesireRatio = (UINT8)GetPlatformCpuBootRatio(gSetupHandle);
+
+ if (DesireRatio == 0 || DesireRatio == 0xff)
+ return;
+
+ if (DesireRatio < MinRatio || DesireRatio > MaxRatio)
+ DesireRatio = MaxRatio;
+
+ ReadWriteMsr(MSR_IA32_MISC_ENABLE, BIT16, (UINT64)-1);
+ WriteMsr(0x199, DesireRatio << 8);
+
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AmiCpuMpServiceCallback
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_EVENT Event --
+// IN VOID * Context --
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID AmiCpuMpServiceCallback(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle=0;
+ EFI_EVENT BootEvent;
+ VOID *FirstHob;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 CpuVer = CpuSignature & 0xf;
+ BOOLEAN X2ApicEnabled = CPULib_IsLocalX2ApicEnabled();
+ UINT32 NumSocketsPop = NumberOfCpuSocketsPopulated();
+ UINT32 i;
+ BOOLEAN IsSandyBridge = (CpuSigNoVer == SANDY_BRIDGE || CpuSigNoVer == JAKETOWN);
+ BOOLEAN IsIvyBridge = (CpuSigNoVer == IVY_BRIDGE);
+ VOID *pRegistration = NULL;
+ MP_CPU_APICID_DATA MpCpuApicIdData;
+ UINT8 *TpmBaseAddr = (UINT8*)0xfed40000;
+
+
+ //MSR 0xCE[28] Programmable Ratio Limits for Turbo Mode Supported
+ BOOLEAN IsXeCoreRatioLimitSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x10000000 ? 1:0;
+ //MSR 0xCE[29] Programmable Ratio Limits for Turbo Mode Supported
+ BOOLEAN IsPwrLimitConfigSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x20000000 ? 1:0;
+ //MSR 0xCE[30] Programmable TCC Acivation Offset Supported
+ BOOLEAN IsTccAcitveOffsetSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x40000000 ? 1:0;
+ //MSR 0xCE[33:34] Programmable TCC Acivation Offset Supported
+ BOOLEAN IsCtdpSupport = Shr64(ReadMsr(MSR_PLATFORM_INFO), 33) & 0x3 ? 1:0;
+ //InitAmiLib(ImageHandle,SystemTable);
+
+ PROGRESS_CODE(DXE_CPU_INIT);
+
+ //Free the memory
+ if (IsFreeMemBelow1MB)
+ pBS->FreePages(gTempBuffer, EFI_SIZE_TO_PAGES(PMM_EBDA_LOMEM_SIZE) - 1);
+
+ //Init global data for later usage
+ Status = GlobalDataInitialize();
+
+ //Create AMI private CpuInfo1 and CpuInfo2 for AMI other module usage
+ CreatePrivateAmiCpuInfo1();
+ CreatePrivateAmiCpuInfo2();
+
+ Status = pBS->InstallProtocolInterface(
+ &TheImageHandle,
+ &gAmiCpuInfo2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gPrivateAmiCpuInfo2
+ );
+
+ Status = pBS->InstallProtocolInterface(
+ &TheImageHandle,
+ &gAmiCpuInfoProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gAmiCpuInfoProtocol
+ );
+
+ // Get CPU feature & set SetupCpuFeatures variable to hide unsupported setup items
+ DxeInitPlatformCpuLib(pBS, pRS, &gSetupHandle);
+
+ FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid);
+ if (!FirstHob) return;
+
+ //Fill CpuInfoHob
+ gCpuInfoHob = (CPUINFO_HOB*)FirstHob;
+
+ //Find CpuInfo Hob & Update it
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION,&gCpuInfoHob))) {
+ if (guidcmp(&gCpuInfoHob->EfiHobGuidType.Name,&gAmiCpuinfoHobGuid) == 0) break;
+ }
+ if (EFI_ERROR(Status)) return;
+
+ for (i = 0; i < gNumOfCpuCores; ++i) {
+ gCpuInfoHob->Cpuinfo[i].ApicId = gEfiMpProcContext[i].ApicID;
+ }
+
+ MpCpuApicIdData.NumberOfCpu = (UINT8)gNumOfCpus;
+ for (i = 0; i < gNumOfCpus; ++i) {
+ MpCpuApicIdData.ApicId[i] = (UINT8)(gEfiMpProcContext[i].ApicID);
+ }
+ Status = pRS->SetVariable(
+ L"CPUS3APICID",
+ &gMpCpuApicIdDataGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof(MP_CPU_APICID_DATA),
+ &MpCpuApicIdData );
+
+
+ gCpuFeatures = gCpuInfoHob->CpuFeatures;
+
+ //Init setup feature data
+#if TCG_SUPPORT || TCG2Support
+ PlatformCpuSmxSupport(gSetupHandle, IsSmxSupported(&gCpuFeatures));
+#else
+ PlatformCpuSmxSupport(gSetupHandle, FALSE);
+#endif
+ PlatformCpuXdSupport(gSetupHandle, isXDSupported(&gCpuFeatures));
+ PlatformCpuLimitCpuidSupport(gSetupHandle, isLimitCpuidSupported());
+ PlatformCpuVtSupport(gSetupHandle, IsVmxSupported(&gCpuFeatures));
+ PlatformCpuHtSupport(gSetupHandle, NumSupportedThreadsPerCore() > 1);
+ PlatformCpuMultiCoreSupport(gSetupHandle, NumSupportedCpuCores() > 1);
+ PlatformCpuMultiSocketSupport(gSetupHandle, NUMBER_CPU_SOCKETS > 1);
+ PlatformCpuMultiSocketPopulated(gSetupHandle, NumberOfCpuSocketsPopulated() > 1);
+ PlatformCpuSocketSetPopulated(gSetupHandle, 0, TRUE);
+ PlatformCpuTccActiveOffsetSupport(gSetupHandle, IsTccAcitveOffsetSupport);
+ PlatformCpuXeCoreRatioLimitSupport(gSetupHandle, IsXeCoreRatioLimitSupport);
+ //All CPU should support Current Limit Programming
+ PlatformCpuCurrentLimitSupport(gSetupHandle, TRUE);
+ PlatformCpuPwrLimitConfigSupport(gSetupHandle, IsPwrLimitConfigSupport);
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ PlatformCpuEistSupport(gSetupHandle, !!(RegEcx & (1 << 7)));
+ PlatformCpuAesSupport(gSetupHandle, !!(gRegEcx & (1 << 25)));
+ PlatformCpuPkgCStateDemotionSupport(gSetupHandle, (RegEax > 0x0306C1));
+ PlatformCpuTurboModeSupport(gSetupHandle, isTurboModeSupported());
+ CPULib_CpuID(5, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ PlatformCpuC3Support(gSetupHandle, !!(RegEdx & C3_SUB_STATES_MASK));
+ PlatformCpuC6Support(gSetupHandle, !!(RegEdx & C6_SUB_STATES_MASK));
+ PlatformCpuC7Support(gSetupHandle, !!(RegEdx & C7_SUB_STATES_MASK));
+ PlatformCpuC8Support(gSetupHandle, !!(RegEdx & C8_SUB_STATES_MASK));
+ PlatformCpuC9Support(gSetupHandle, !!(RegEdx & C9_SUB_STATES_MASK));
+ PlatformCpuC10Support(gSetupHandle, !!(RegEdx & C10_SUB_STATES_MASK));
+ PlatformCpuCtdpSupport(gSetupHandle, IsCtdpSupport);
+ PlatformTpmDevicePresent(gSetupHandle, (*TpmBaseAddr != 0xff));
+
+ Status = DxePlatformCpuSaveSupportedData(pRS);
+ ASSERT_EFI_ERROR(Status);
+
+#if CPU_SETUP_SET_BOOT_RATIO
+ CpuSetBootRatio();
+#endif
+
+#if CPU_MODULE_CREATE_SMBIOS_TABLES == 1
+ CpuSmbios();
+#endif
+
+ Status = pBS->CreateEvent(
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ PrepareToBoot,
+ (VOID*)TRUE,
+ &BootEvent
+ );
+ ASSERT_EFI_ERROR(Status);
+
+#ifdef CSM_SUPPORT
+
+ Status = RegisterProtocolCallback(
+ &gAmiLegacyBootProtocolGuid,
+ PrepareToBoot,
+ NULL,
+ &BootEvent,
+ &pRegistration );
+
+#endif
+
+ CpuDxeMiscFuncs();
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AmiCpuSmmFeatureEnCallbacks
+//
+// Description: Callback for trigger SMI to enable Cpu SMM feature in SMM
+//
+// Input:
+// IN EFI_EVENT Event --
+// IN VOID * Context --
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AmiCpuSmmFeatureEnCallbacks(IN EFI_EVENT Event, IN VOID *Context)
+{
+
+#ifdef SW_SMI_ENABLE_SMM_FEATURE
+ pBS->CloseEvent(Event);
+#if SMM_ACCESS_CHECK_ENABLE
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_ENABLE_SMM_FEATURE);
+#endif
+#endif
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DxeInitializeCpu
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle -- Handle assigned to this driver.
+// IN EFI_SYSTEM_TABLE *SystemTable -- Efi System table.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeInitializeCpu(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ AMI_BEFORE_CPU_RC_PROTOCOL *AmiBeforeCpuRcProtocol;
+
+#if AMI_PEI_DEBUG_SUPPORT
+ AMI_DEBUGGER_CPU_PROTOCOL *AmiDebuggerCpuProtocol;
+#endif
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ // Get CPU support feature before CPU RC DXE initialize
+ CPULib_CpuID(1, &gRegEax, &gRegEbx, &gRegEcx, &gRegEdx);
+
+ Status = RegisterProtocolCallback(
+ &gEfiMpServicesProtocolGuid,
+ AmiCpuMpServiceCallback,
+ NULL,
+ &gAmiMpEvent,
+ &gAmiMpEventRegistration
+ );
+
+ Status = RegisterProtocolCallback(
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ AmiCpuSmmFeatureEnCallbacks,
+ NULL,
+ &gSmmFeaEnEvent,
+ &gSmmFeaEnReg
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(AMI_BEFORE_CPU_RC_PROTOCOL),
+ (VOID**)&AmiBeforeCpuRcProtocol );
+
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gAmiBeforeCpuRcProtocolGuid, AmiBeforeCpuRcProtocol,
+ NULL );
+#if AMI_PEI_DEBUG_SUPPORT
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(AMI_DEBUGGER_CPU_PROTOCOL),
+ (VOID**)&AmiDebuggerCpuProtocol );
+
+ AmiDebuggerCpuProtocol->DebuggerGetAptioIntHandler = DebuggerGetAptioInterruptHandlerHalt;
+ AmiDebuggerCpuProtocol->DebuggerFixUpPEIExceptionHandlers = DebuggerFixUpPEIDebuggerExceptionHandlers;
+ AmiDebuggerCpuProtocol->DebuggerSetupExceptionHandler = DebuggerSetupPEIDebuggerExceptionHandlers;
+ AmiDebuggerCpuProtocol->DebuggerIsDebuggerIrqHadler = DebuggerIsItPEIDebugIRQHandlerToHookup;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gAmiDebuggerCpuProtocolGuid, AmiDebuggerCpuProtocol,
+ NULL );
+#endif
+
+ gTempBuffer = 0xA0000 - PMM_EBDA_LOMEM_SIZE;
+ IsFreeMemBelow1MB = FALSE;
+ Status = pBS->AllocatePages (
+ AllocateAddress,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(PMM_EBDA_LOMEM_SIZE) - 1,
+ &gTempBuffer
+ );
+
+ if (!EFI_ERROR(Status))
+ IsFreeMemBelow1MB = TRUE;
+
+ return EFI_SUCCESS;
+
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuDxe.dxs b/Core/CPU/CpuDxe.dxs
new file mode 100644
index 0000000..e6d6ced
--- /dev/null
+++ b/Core/CPU/CpuDxe.dxs
@@ -0,0 +1,57 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.dxs 1 2/07/12 3:58a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:58a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.dxs $
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CPUDXE.dxs
+//
+// Description: Dependency expression for Cpu Dxe.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuDxe.h b/Core/CPU/CpuDxe.h
new file mode 100644
index 0000000..aeb5015
--- /dev/null
+++ b/Core/CPU/CpuDxe.h
@@ -0,0 +1,158 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.h 2 1/14/13 1:54a Crystallee $
+//
+// $Revision: 2 $
+//
+// $Date: 1/14/13 1:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.h $
+//
+// 2 1/14/13 1:54a Crystallee
+// [TAG] EIP111199
+// [Category] Improvement
+// [Description] Provide variable data which constains number of P
+// states support.
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxe.h
+//
+// Description: Cpu Dxe header file.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_DXE_H__
+#define __CPU_DXE_H__
+
+#include <AmiHobs.h>
+#include <Protocol\Cpu.h>
+#include <Protocol\MpService\MpService.h>
+#include <Protocol\AmiCpuInfo2.h>
+#include "Cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Define structures used and referenced in this file
+typedef struct{
+ UINT16 NumberOfPStates;
+} P_STATES_DATA;
+
+typedef struct{
+ UINT32 MemAddress, MemLength;
+} system_memory_struc;
+
+EFI_STATUS EfiCpuFlushDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType);
+
+EFI_STATUS EfiCpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes);
+
+extern EFI_MP_SERVICES_PROTOCOL *gEfiMpServicesProtocol;
+
+//APIC ID
+//CPU NUM
+#define PRIVATE_INFO_NUM_OF_CPU_DATA 2
+
+typedef struct {
+ AMI_CPU_INFO_2_PROTOCOL AmiCpuInfo2;
+//??? Determine max structure size of UINT32s
+ // UINT32 # of populated Sockets 0
+ // ---------------------
+ // ---------------------
+ // ---Socket #0---
+ // UINT32 # of Cores
+ // ---Core #0---
+ // UINT32 # of Threads
+ // ---Thread #0---
+ // UINT32 APIC ID
+ // UINT32 CPU Num
+ // ---Thread #1---
+ // UINT32 APIC ID
+ // UINT32 CPU Num
+ // ---Core #1---
+ // ....
+ // ---------------------
+ // ---------------------
+ // ---Socket #1---
+ // UINT32 # of Cores
+ // ---Core # 0---
+ // UINT32 # of Threads
+ // ---Thread #0---
+ // ....
+} PRIVATE_AMI_CPU_INFO_2_PROTOCOL;
+
+extern PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+
+typedef struct _AMI_BEFORE_CPU_RC_PROTOCOL AMI_BEFORE_CPU_RC_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *PLATFORM_CPU_DXE_POLICY_OVERWRITE) (
+ IN AMI_BEFORE_CPU_RC_PROTOCOL *This
+
+ );
+
+typedef struct _AMI_BEFORE_CPU_RC_PROTOCOL {
+ PLATFORM_CPU_DXE_POLICY_OVERWRITE PlatformCpuDxePolicyOverwrite;
+};
+
+VOID CpuDxeMiscFuncs(VOID);
+
+#if PERF_TUNE_SUPPORT == 1
+
+EFI_STATUS IntelXtuFillCpuDataCallBack(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+#endif
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuDxeFuncs.c b/Core/CPU/CpuDxeFuncs.c
new file mode 100644
index 0000000..dea230d
--- /dev/null
+++ b/Core/CPU/CpuDxeFuncs.c
@@ -0,0 +1,1101 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxeFuncs.c 10 5/06/14 12:03a Hsingyingchung $
+//
+// $Revision: 10 $
+//
+// $Date: 5/06/14 12:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxeFuncs.c $
+//
+// 10 5/06/14 12:03a Hsingyingchung
+// [TAG] EIP167029
+// [Category] Improvement
+// [Description] 1. keep the original attribute of "Setup" variable when
+// use SetVariable().
+// 2. remove the runtime attribute of variables that no access requirement
+// in runtime.
+//
+// 9 6/03/13 12:12a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description]
+// 1. Change PLL defatul value to LCPLL
+// 2. Modify IA core ratio minimun value. Use "max non turbo ratio(MSR
+// CEh)" instead of "power on turbo default value".
+// 3. Remove write MSR 620h due to RC have implemented (EIP123446).
+//
+// 8 4/07/13 11:58p Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description] Keep ring ratio default value in ACPI table when one
+// core ratio has changed.
+//
+// 7 3/05/13 1:10a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Use OcSetupData for EIST and Turbo status when
+// PerformanceTunning enable
+//
+// 6 2/07/13 4:08a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description]
+// Add:
+// 1. Support IA core and Ring voltage offset negative in OC mailbox.
+// 2. Add Filter PLL function, please change
+// "HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT" token if need to use this
+// function.
+//
+// Fixed:
+// 1. TDP Time Window is now programmed to 8 seconds by default.
+// 2. When cold reset, re-enabling FIVR faults and SVID control.
+// 3. Assign max ring ratio in msr 0x620 with ring ratio max value
+// support.
+//
+// 5 1/14/13 1:54a Crystallee
+// [TAG] EIP111199
+// [Category] Improvement
+// [Description] Provide variable data which constains number of P
+// states support.
+//
+// 4 12/20/12 10:25a Hsingyingchung
+//
+// 3 12/20/12 10:21a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 2 11/23/12 2:09a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxeFuncs.c
+//
+// Description:
+// Installs CPU Architectural Protocol.
+// processor interrupt vector table. The CPU Architectural
+// Protocol enables/disables/get state of interrupts, set
+// memory range cache type, and installs/uninstalls
+// interrupt handlers.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Setup.h>
+#include <token.h>
+#include <AmiCspLib.h>
+#include <Protocol\AmiCpuInfo.h>
+#include "CpuDxe.h"
+
+extern EFI_SYSTEM_TABLE *pST;
+extern EFI_BOOT_SERVICES *pBS;
+extern EFI_RUNTIME_SERVICES *pRS;
+
+extern EFI_GUID gHobListGuid;
+
+#if PERF_TUNE_SUPPORT == 1
+#include <Protocol\PerfTuneProtocol.h>
+#include "Board\EM\PerfTune\PerfTuneCpuSetup.h"
+
+static EFI_GUID gAmiInternalFactoryTdcTdpHobGuid = AMI_INTERNAL_FACTORY_TDC_TDP_HOB_GUID;
+static EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+
+AMI_INTERNAL_FACTORY_TDC_TDP_HOB *gTdcTdpHob = NULL;
+CPU_RATIO_LIMIT_DATA *gCpuRatioLimitData = NULL;
+
+OVERCLOCKING_CONFIG_DATA *gOcConfigData;
+EFI_GUID InternalWdtGuid = PERF_TUNE_WDT_PROTOCOL_GUID;
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID \
+ { \
+ 0xd71db106, 0xe32d, 0x4225, 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 \
+ }
+
+#else
+#define EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID \
+ { \
+ 0xd71db106, 0xe32d, 0x4225, \
+ { \
+ 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 \
+ } \
+ }
+#endif
+EFI_GUID gPowerMgmtInitDoneProtocolGuid = EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+
+#define DXE_PLATFORM_ME_POLICY_GUID \
+ { 0x69bf9e8a, 0x4ad6, 0x9a28, 0x87, 0xf3, 0x09, 0xa0, 0x71, 0x29, 0x2a, 0x00}
+EFI_GUID gDxePlatformMePolicyGuid = DXE_PLATFORM_ME_POLICY_GUID;
+
+#define ME_INFO_SETUP_GUID \
+ { 0x78259433, 0x7B6D, 0x4DB3, 0x9A, 0xE8, 0x36, 0xC4, 0xC2, 0xC3, 0xA1, 0x7D}
+EFI_GUID gMeSetupInfoGuid = ME_INFO_SETUP_GUID;
+
+#define AMI_CPU_INTERNAL_ME_FW_VERSION_GUID \
+ { 0x9b875aac, 0x36ec, 0x4550, 0xa4, 0xae, 0x86, 0xc8, 0x4e, 0x96, 0x76, 0x7e}
+EFI_GUID gAmiCpuMEFwVerGuid = AMI_CPU_INTERNAL_ME_FW_VERSION_GUID;
+typedef struct{
+ UINT8 MeFirmwareInfo;
+ UINT32 MeMajor;
+ UINT32 MeMinor;
+ UINT32 MeHotFix;
+ UINT32 MeBuildNo;
+} ME_INFO_SETUP_DATA;
+
+BIOS_SETTING_DATA *gBiosSettingData;
+#endif
+
+#ifndef FVID_MAX_STATES
+#define FVID_MAX_STATES 16
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumberOfPStatesSupport
+//
+// Description: Provide variable data which constains number of P states support
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NumberOfPStatesSupport(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gSetupGuid = SETUP_GUID;
+#if PERF_TUNE_SUPPORT == 1
+ UINTN SetupDataSize = sizeof(OC_SETUP_DATA);
+ OC_SETUP_DATA SetupData;
+#else
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+ SETUP_DATA SetupData;
+#endif
+ P_STATES_DATA PStatesData;
+ UINT16 mMaxBusRatio;
+ UINT16 mMinBusRatio;
+ UINT16 BusRatioRange;
+ UINT64 MsrPlatformInfo;
+
+#if PERF_TUNE_SUPPORT == 1
+ Status = pRS->GetVariable(L"OcSetupData",&gSetupGuid, NULL, &SetupDataSize, &SetupData);
+#else
+ Status = pRS->GetVariable(L"Setup",&gSetupGuid, NULL, &SetupDataSize, &SetupData);
+#endif
+ if(EFI_ERROR(Status)) {
+ TRACE((-1,"Get Setup variable fail!!\n"));
+ return;
+ }
+
+ if (!EFI_ERROR(Status)) {
+ if (!SetupData.EIST) {
+ PStatesData.NumberOfPStates = 0;
+ }
+ else {
+ MsrPlatformInfo = ReadMsr(0xce);
+ mMaxBusRatio = (UINT16)(Shr64(MsrPlatformInfo, 8) & 0xff);
+ mMinBusRatio = (UINT16)(Shr64(MsrPlatformInfo, 40) & 0xff);
+ BusRatioRange = mMaxBusRatio - mMinBusRatio;
+
+ PStatesData.NumberOfPStates = ((BusRatioRange + 1) < FVID_MAX_STATES ? (BusRatioRange + 1) : FVID_MAX_STATES);
+
+ if (SetupData.TurboMode & isTurboModeSupported()) {
+ if (PStatesData.NumberOfPStates == FVID_MAX_STATES)
+ PStatesData.NumberOfPStates--;
+ }
+ }
+
+ Status = pRS->SetVariable(
+ L"NumOfPState",
+ &gSetupGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(P_STATES_DATA),
+ &PStatesData
+ );
+ if(EFI_ERROR(Status)) {
+ TRACE((-1,"Set number of P states variable fail!!\n"));
+ }
+ }
+}
+
+#if PERF_TUNE_SUPPORT == 1
+
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillXtuGaciData
+//
+// Description: Fill CPU information for xtu 3.0 specification
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FillXtuGaciData(
+ IN PERF_TUNE_ASL_PROTOCOL *PerfTuneAslProtocol
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT8 *Buffer = NULL;
+ UINT8 *ptr = NULL;
+ UINTN Len = 0;
+ UINT64 PlatformInfo = ReadMsr(MSR_PLATFORM_INFO);
+ UINT16 Bins = Shr64(ReadMsr(MSR_FLEX_RATIO),17) & 0x7; //overclocking bins supported
+ UINT16 MNTR = gBiosSettingData->ProcessorMul;
+
+ //----------------------------CPU Ratio GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuMulGaciData = {BIOS_PROC_MULT_IMPLEMENTATION, 0x0, 0, 0, 0, 0, 0, 0, 0};
+
+ //----------------------------CPU TDC GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuTdcGaciData = {BIOS_TDC_VALUE_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+
+ //----------------------------CPU TDP GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuTdpGaciData = {BIOS_TDP_VALUE_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+
+ //-------------------TOTAL DESIGN POWER LOCK SWITCH DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ExtTDPSwGaciData= {BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 0, 0, 1, 0, 1};
+
+ //----------------------------CPU Core Ratio Limit GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu1CoreRatioLimGaci = {BIOS_1_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu2CoreRatioLimGaci = {BIOS_2_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu3CoreRatioLimGaci = {BIOS_3_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu4CoreRatioLimGaci = {BIOS_4_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu5CoreRatioLimGaci = {BIOS_5_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu6CoreRatioLimGaci = {BIOS_6_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+
+ //----------------------------CPU Turbo Mode GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA TurboModeGaciData = {BIOS_TURBO_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------CPU Max Turbo Mode Cpu Voltage GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA TMCpuVoltGaci = {BIOS_MAX_TURBO_MODE_CPU_VOLTAGE_IMPLEMENTATION, 256, 5, 0, 0, 0, 255, 0, 99609375};
+
+ //----------------------------CPU EIST GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA EistGaciData = {BIOS_EIST_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------CPU TDP Related GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ShortTDPSwGaciData= {BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ShortTdpGaci = {BIOS_SHORT_TDP_IMPLEMENTATION, 513, 0, 0, 0, 0, 512, 0, 512};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ //static GACI_DATA ExtTdpGaci = {BIOS_EXTENDED_TDP_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+ static GACI_DATA ExtTdpGaci = {BIOS_EXTENDED_TDP_IMPLEMENTATION, 513, 0, 0, 0, 0, 512, 0, 512};
+
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ExtTdpTimeGaci = {BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION, 0xFFFF, 0, 0, 1, 0, 0, 0, 0};
+
+ //----------------------------IA CORE CURRENT MAX--------------------------
+ // GACI_DATA DevNameGaciData { ControlID, NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA IACoreAmpGaci = {BIOS_PACKAGE_CURRENT_LIMIT_IMPLEMENTATION, 8192, 3, 0, 0, 0, 8191, 0, 1023875};
+
+ //----------------------------IGFX CORE CURRENT MAX--------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ //static GACI_DATA iGFXCoreAmpGaci = {BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION, 8192, 3, 0, 0, 0, 8191, 0, 1023875};
+
+
+ //----------------------------INTERNAL PLL Overvoltage Enable--------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA iPLLOvGaci = {BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 0, 0, 1, 0, 1};
+
+ //----------------------------Overclocking Lock GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA OverclockingGaciData = {BIOS_OVERCLOCKING_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------Overclocking Related GACI DATA----------------------------
+ //IA core
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltOverrideGaci = {BIOS_CPU_VOLTAGE_IMPLEMENTATION, 2001, 3, 0, 0, 0, 2000, 0, 2000};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltModeGaci = {BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION, 2, 0, 0, 0, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltOffsetGaci = {BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION, 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+ //RING
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGRatioGaci = { BIOS_RING_RATIO_IMPLEMENTATION, 1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltOverrideGaci = {BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION, 2001, 3, 0, 0, 0, 2000, 0, 2000};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltModeGaci = {BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION, 2, 0, 0, 0, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltOffsetGaci = {BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION, 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+ //SVID and FIVR
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA SVIDControlGaci = {BIOS_DYNAMIC_SVID_CONTROL_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA SVIDVoltOverrideGaci = {BIOS_SVID_VOLTAGE_OVERRIDE_IMPLEMENTATION, 2501, 3, 0, 0, 0, 2500, 0, 2500};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA FivrFaultsGaciData = {BIOS_FIVR_FAULTS_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA FivrEfficiencyGaciData = {BIOS_FIVR_EFFICIENCY_MANAGEMENT_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ //Filter PLL Frequency
+ static GACI_DATA FilterPLLGaciData = {BIOS_FILTER_PLL_FREQUENCY_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+#endif
+
+ TRACE((-1, "XTU Fill XTU Cpu Gaci data\n"));
+
+ //--1. CPU ratio GACI DATA--------------------------------------------
+ //CpuMulGaciData.MinDataValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ //CpuMulGaciData.MaxDataValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //CpuMulGaciData.MinDisplayValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ //CpuMulGaciData.MaxDisplayValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //CpuMulGaciData.NumberOfValues = CpuMulGaciData.MaxDataValue - CpuMulGaciData.MinDataValue + 1;
+ //CpuMulGaciData.DefaultDataValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //Len = sizeof(GACI_DATA);
+ //Buffer = MallocZ(Len);
+ //if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ //MemCpy(Buffer, &CpuMulGaciData, sizeof(CpuMulGaciData));
+ //Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ //pBS->FreePool(Buffer);
+ CpuMulGaciData.MinDataValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ CpuMulGaciData.MaxDataValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ CpuMulGaciData.MinDisplayValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ CpuMulGaciData.MaxDisplayValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ CpuMulGaciData.NumberOfValues = CpuMulGaciData.MaxDataValue - CpuMulGaciData.MinDataValue + 1;
+ CpuMulGaciData.DefaultDataValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CpuMulGaciData, sizeof(CpuMulGaciData));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //--2. CPU TDC GACI DATA--------------------------------------------
+ CpuTdcGaciData.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc);
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &CpuTdcGaciData, Len);
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //--3. CPU TDP GACI DATA--------------------------------------------
+ CpuTdpGaciData.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp);
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &CpuTdpGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--4. TOTAL DESIGN POWER LOCK SWITCH DATA----------------------------
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &ExtTDPSwGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--5. CPU Cores ratio limit GACI DATA--------------------------------------------
+ Cpu1CoreRatioLimGaci.MinDataValue = MNTR;
+ Cpu1CoreRatioLimGaci.MinDisplayValue = MNTR;
+
+ MemCpy(&(Cpu2CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu3CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu4CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu5CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu6CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+
+ Cpu1CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->OneCoreRatioLimit + (UINT16)Bins;
+ Cpu1CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->OneCoreRatioLimit + (UINT16)Bins;
+ Cpu1CoreRatioLimGaci.NumberOfValues = Cpu1CoreRatioLimGaci.MaxDataValue - Cpu1CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu2CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->TwoCoreRatioLimit + (UINT16)Bins;
+ Cpu2CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->TwoCoreRatioLimit + (UINT16)Bins;
+ Cpu2CoreRatioLimGaci.NumberOfValues = Cpu2CoreRatioLimGaci.MaxDataValue - Cpu2CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu3CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->ThreeCoreRatioLimit + (UINT16)Bins;
+ Cpu3CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->ThreeCoreRatioLimit + (UINT16)Bins;
+ Cpu3CoreRatioLimGaci.NumberOfValues = Cpu3CoreRatioLimGaci.MaxDataValue - Cpu3CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu4CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FourCoreRatioLimit + (UINT16)Bins;
+ Cpu4CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FourCoreRatioLimit + (UINT16)Bins;
+ Cpu4CoreRatioLimGaci.NumberOfValues = Cpu4CoreRatioLimGaci.MaxDataValue - Cpu4CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu5CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FiveCoreRatioLimit + (UINT16)Bins;
+ Cpu5CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FiveCoreRatioLimit + (UINT16)Bins;
+ Cpu5CoreRatioLimGaci.NumberOfValues = Cpu5CoreRatioLimGaci.MaxDataValue - Cpu5CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu6CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->SixCoreRatioLimit + (UINT16)Bins;
+ Cpu6CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->SixCoreRatioLimit + (UINT16)Bins;
+ Cpu6CoreRatioLimGaci.NumberOfValues = Cpu6CoreRatioLimGaci.MaxDataValue - Cpu6CoreRatioLimGaci.MinDataValue + 1;
+
+ gTdcTdpHob->OneCoreRatioMax = Cpu1CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->TwoCoreRatioMax = Cpu2CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->ThreeCoreRatioMax = Cpu3CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->FourCoreRatioMax = Cpu4CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->FiveCoreRatioMax = Cpu5CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->SixCoreRatioMax = Cpu6CoreRatioLimGaci.MaxDataValue;
+
+
+ Cpu1CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->OneCoreRatioLimit);
+ Cpu2CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->TwoCoreRatioLimit);
+ Cpu3CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->ThreeCoreRatioLimit);
+ Cpu4CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->FourCoreRatioLimit);
+ Cpu5CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->FiveCoreRatioLimit);
+ Cpu6CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->SixCoreRatioLimit);
+
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &Cpu1CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit1)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu2CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit2)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu3CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit3)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu4CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit4)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu5CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit5)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu6CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit6)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ pBS->FreePool(Buffer);
+ pBS->FreePool(gBiosSettingData);
+
+ //--6. Turbo Mode GACI DATA--------------------------------------------
+ Len = sizeof(TurboModeGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &TurboModeGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--7. Max Turbo Mode CPU Voltage-------------------------------------
+ Len = sizeof(TMCpuVoltGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &TMCpuVoltGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--8. CPU EIST GACI DATA-------------------------------------
+ Len = sizeof(EistGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &EistGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--9. ShortTdpGaci------------------------------------------
+ //ShortTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc);
+ ShortTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc / 8 );
+ Len = sizeof(ShortTdpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ShortTdpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //-- ShortTDPSwGaci------------------------------------------
+ Len = sizeof(ShortTDPSwGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ShortTDPSwGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--10.ExtTdpGaci------------------------------------------
+ //ExtTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp);
+ ExtTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp / 8 );
+ Len = sizeof(ExtTdpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ExtTdpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //-- ExtTdpTimeGaci------------------------------------------
+ ExtTdpTimeGaci.DefaultDataValue = 8; // For desktop, default is 8.
+ Len = sizeof(ExtTdpTimeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ExtTdpTimeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //11.IA CORE CRUUENT MAX----------------------------------------------------
+ IACoreAmpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->IaCoreCurrentMax);
+ Len = sizeof(IACoreAmpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &IACoreAmpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //12.iGFX CORE CURRENT MAX--------------------------------------------------
+ //iGFXCoreAmpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->IGfxCoreCurrentMax);
+ //Len = sizeof(iGFXCoreAmpGaci);
+ //Buffer = MallocZ(Len);
+ //if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ //MemCpy(Buffer, &iGFXCoreAmpGaci, sizeof(GACI_DATA));
+ //Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ //pBS->FreePool(Buffer);
+
+
+ //13.INTERNAL PLL OVERVOLTAGE ENABLE---------------------------
+ Len = sizeof(iPLLOvGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &iPLLOvGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--14. Overclocking Enable GACI DATA-------------------------------------
+ Len = sizeof(OverclockingGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &OverclockingGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+ //--15. Overclocking Feature GACI DATA-------------------------------------
+//IA core
+ //CPU voltage override
+ Len = sizeof(CPUVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //IA core voltage mode
+ Len = sizeof(CPUVoltModeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltModeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Dynamic CPU Voltage Offset
+ Len = sizeof(CPUVoltOffsetGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltOffsetGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//CLR/RING
+ //Ring Ratio
+ RINGRatioGaci.MaxDataValue = (UINT16)gOcConfigData->OCCap[RING].MaxOcRatioLimit;
+ RINGRatioGaci.MaxDisplayValue = (UINT16)gOcConfigData->OCCap[RING].MaxOcRatioLimit;
+ RINGRatioGaci.NumberOfValues = RINGRatioGaci.MaxDataValue - RINGRatioGaci.MinDataValue + 1;
+ RINGRatioGaci.DefaultDataValue = (UINT16)gTdcTdpHob->OneCoreRatioLimit;
+ Len = sizeof(RINGRatioGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGRatioGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Override
+ Len = sizeof(RINGVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Mode
+ Len = sizeof(RINGVoltModeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltModeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Offset
+ Len = sizeof(RINGVoltOffsetGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltOffsetGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//SVID and FIVR
+ //SVID Voltage Override
+ Len = sizeof(SVIDVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &SVIDVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //SVID Control Enable/Disable
+ Len = sizeof(SVIDControlGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &SVIDControlGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if(gOcConfigData->IsPowerCycle)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)1); // Re-Enable SVID Control if cold boot
+ pBS->FreePool(Buffer);
+
+ //FIVR FAULTS DISABLE
+ Len = sizeof(FivrFaultsGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FivrFaultsGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if(gOcConfigData->IsPowerCycle)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)1); // Re-Enable FIVR FAULTS if cold boot
+ pBS->FreePool(Buffer);
+
+ //FIVR EFFICIENCY DISABLE
+ Len = sizeof(FivrEfficiencyGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FivrEfficiencyGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ pBS->FreePool(gCpuRatioLimitData);
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ //Filter PLL
+ Len = sizeof(FilterPLLGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FilterPLLGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+#endif
+
+ return EFI_SUCCESS;
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IntelXtuFillCpuDataCallBack
+//
+// Description: Callback function for Intel XTU data init
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IntelXtuFillCpuDataCallBack(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ EFI_GUID PerfTuneAslProtocolGuid = PERF_TUNE_ASL_PROTOCOL_GUID;
+ PERF_TUNE_ASL_PROTOCOL *PerfTuneAslProtocol = NULL;
+
+ TRACE((-1, "XTU Fill Cpu Data Callback\n"));
+
+ Status = pBS->LocateProtocol(&PerfTuneAslProtocolGuid, NULL, &PerfTuneAslProtocol);
+ if(!EFI_ERROR(Status))
+ FillXtuGaciData(PerfTuneAslProtocol);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CpuPllOverVoltageProgress
+//
+// Description: CPU pll over voltage initialize code in DXE phase
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPllOverVoltageProgress(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_GUID AmiPllOvFlagHobGuid = AMI_PLL_OVER_VOTAGE_FLAG_HOB_GUID;
+ EFI_GUID AmiPllOvFlagDataGuid = AmiPllOvFlagHobGuid;
+ EFI_GUID gHobListGuid = HOB_LIST_GUID;
+ PLL_OV_FLAG_DATA_HOB *PllOvFlagDataHob;
+ UINT64 CoreRatioLimits = ReadMsr(0x1ad);
+ EFI_STATUS Status = EFI_NOT_STARTED;
+ VOID *FirstHob;
+ PERF_TUNE_WDT_PROTOCOL *InternalWdtProtocol;
+
+ TRACE((-1,"CpuPllOverVoltageProgress Start\n"));
+
+ // Get Hob List
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+ if (!FirstHob) return EFI_NOT_READY;
+
+ PllOvFlagDataHob = (PLL_OV_FLAG_DATA_HOB*)FirstHob;
+
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION,&PllOvFlagDataHob))) {
+ if (guidcmp(&PllOvFlagDataHob->EfiHobGuidType.Name,&AmiPllOvFlagHobGuid) == 0) break;
+ }
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ Status = EFI_ALREADY_STARTED;
+
+ if((PllOvFlagDataHob->PllOvData.PLLOvFlag == 0x1) && (CoreRatioLimits = 0x060606))
+ {
+ //Delay for 1.5 ms
+ pBS->Stall(150);
+
+ PllOvFlagDataHob->PllOvData.PLLOvFlag = 0x2;
+
+ //write back original Core Ratio Limits.
+ WriteMsr(0x1ad, PllOvFlagDataHob->PllOvData.OriTurboRatio);
+
+ Status = pRS->SetVariable(
+ L"PLLOvFlag",
+ &AmiPllOvFlagDataGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(PLL_OV_FLAG_DATA),
+ &PllOvFlagDataHob->PllOvData
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&InternalWdtGuid, NULL, &InternalWdtProtocol);
+ if(!EFI_ERROR(Status))
+ {
+ TRACE((-1,"Internal PLL Over Voltage Reset Requirement.\n"));
+ //reset
+ InternalWdtProtocol->AllowKnownReset();
+ IoWrite8 (0xCF9,0x02);
+ IoWrite8 (0xCF9,0x06);
+ EFI_DEADLOOP();
+ }
+ }else if(PllOvFlagDataHob->PllOvData.PLLOvFlag== 0x2) {
+ //Clear Flag to Zero
+ PllOvFlagDataHob->PllOvData.PLLOvFlag = 0x0;
+ Status = pRS->SetVariable(
+ L"PLLOvFlag",
+ &AmiPllOvFlagDataGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(PLL_OV_FLAG_DATA),
+ &PllOvFlagDataHob->PllOvData
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1,"Clear Pll Overvoltage Flag %r.\n",Status));
+ }
+
+ TRACE((-1,"CpuPllOverVoltageProgress End\n"));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveMEFWVersion
+//
+// Description: CPU pll over voltage initialize code in DXE phase
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveMEFWVersion(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ ME_INFO_SETUP_DATA MeInfoSetupData;
+ UINTN DataSize = sizeof(ME_INFO_SETUP_DATA);
+
+ TRACE((-1,"SaveMEFWVersion start!!\n"));
+
+ pBS->CloseEvent( Event);
+ Status = pRS->GetVariable(
+ L"MeInfoSetup",
+ &gMeSetupInfoGuid,
+ NULL,
+ &DataSize,
+ &MeInfoSetupData
+ );
+ if(EFI_ERROR(Status)){
+ TRACE((-1,"Get ME firmware version fail!!\n"));
+ return Status;
+ }
+
+ Status = pRS->SetVariable(
+ L"MEFWVersion",
+ &gAmiCpuMEFwVerGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(ME_INFO_SETUP_DATA),
+ &MeInfoSetupData
+ );
+ if(EFI_ERROR(Status)){
+ TRACE((-1,"Set ME firmware version fail!!\n"));
+ return Status;
+ }
+
+ TRACE((-1,"SaveMEFWVersion end!!\n"));
+
+ return Status;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuDxeMiscFuncs
+//
+// Description:
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CpuDxeMiscFuncs(VOID)
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+#if PERF_TUNE_SUPPORT == 1
+ {
+
+ EFI_GUID PerfTuneAslProtocolGuid = PERF_TUNE_ASL_PROTOCOL_GUID;
+ EFI_EVENT IntelXtuCpuCallbackEvt;
+ VOID *IntelXtuCpuCallbackReg;
+ VOID *FirstHob;
+ EFI_EVENT PllOvCallbackEvt;
+ VOID *PllOvCallbackReg;
+ EFI_EVENT MEFWCallbackEvt;
+ VOID *MEFWCallbackReg;
+ EFI_GUID gAmiPerfTuneDataHobGuid = AMI_PERF_TUNE_DATA_HOB_GUID;
+ EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+ UINTN DataSize;
+ OVERCLOCKING_CONFIG_HOB *OcConfigHob = NULL;
+ CPU_RATIO_LIMIT_HOB *CpuRatioLimitHob = NULL;
+ UINT32 Attributes = 0;
+
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+
+ //If First boot or CPU change is detected, record new MaxNonTurboRatio.
+ CpuRatioLimitHob = (CPU_RATIO_LIMIT_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &CpuRatioLimitHob))) {
+ if (guidcmp(&CpuRatioLimitHob->EfiHobGuidType.Name, &gAmiCpuRatioLimitHobGuid) == 0){
+ if(CpuRatioLimitHob->IsChangeCpu){
+ Status = pRS->SetVariable(
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(CPU_RATIO_LIMIT_DATA),
+ &CpuRatioLimitHob->CpuRatioLimitData );
+ ASSERT_EFI_ERROR(Status);
+ }
+ break;
+ }
+ }
+
+ // get TdcTdpHob.
+ gTdcTdpHob = (AMI_INTERNAL_FACTORY_TDC_TDP_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &gTdcTdpHob))) {
+ if (guidcmp(&gTdcTdpHob->EfiHobGuidType.Name, &gAmiInternalFactoryTdcTdpHobGuid) == 0){
+
+ Status = RegisterProtocolCallback(
+ &PerfTuneAslProtocolGuid,
+ IntelXtuFillCpuDataCallBack,
+ NULL,
+ &IntelXtuCpuCallbackEvt,
+ &IntelXtuCpuCallbackReg
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ break;
+ }
+ }
+ if(!EFI_ERROR(Status)){
+ // get overclocking config HOB
+ OcConfigHob = (OVERCLOCKING_CONFIG_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OcConfigHob))) {
+ if (guidcmp(&OcConfigHob->EfiHobGuidType.Name, &gAmiOcConfigHobGuid) == 0){
+ break;
+ }
+ }
+ gOcConfigData = NULL;
+ if(!EFI_ERROR(Status))
+ gOcConfigData = &OcConfigHob->OverclockData;
+ else
+ ASSERT_EFI_ERROR(Status);
+
+ // get Cpu ratio limit default value.
+ DataSize = sizeof(CPU_RATIO_LIMIT_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &gCpuRatioLimitData);
+ Status = pRS->GetVariable(
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ NULL,
+ &DataSize,
+ gCpuRatioLimitData );
+ ASSERT_EFI_ERROR(Status);
+
+ // Restores default value when Cpu change or watch dog timeout.
+ if( gOcConfigData->IsCpuRunDefault ){
+ SETUP_DATA *SetupData;
+ DataSize = sizeof(SETUP_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &SetupData);
+ Status = pRS->GetVariable(
+ L"Setup",
+ &gSetupGuid,
+ &Attributes,
+ &DataSize,
+ SetupData
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ SetupData->LcSbSelect = 0;
+ SetupData->PackageCurrentLock = 0;
+
+ Status = pRS->SetVariable(
+ L"Setup",
+ &gSetupGuid,
+ Attributes,
+ sizeof(SETUP_DATA),
+ SetupData
+ );
+ ASSERT_EFI_ERROR(Status);
+ pBS->FreePool(SetupData);
+ }
+
+ // get current setting data of XTU
+ DataSize = sizeof(BIOS_SETTING_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &gBiosSettingData);
+ Status = pRS->GetVariable(
+ L"OcCurrent",
+ &gSetupGuid,
+ NULL,
+ &DataSize,
+ gBiosSettingData);
+ }
+
+ Status = RegisterProtocolCallback(
+ &InternalWdtGuid,
+ CpuPllOverVoltageProgress,
+ NULL,
+ &PllOvCallbackEvt,
+ &PllOvCallbackReg );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = RegisterProtocolCallback(
+ &gDxePlatformMePolicyGuid,
+ SaveMEFWVersion,
+ NULL,
+ &MEFWCallbackEvt,
+ &MEFWCallbackReg);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ NumberOfPStatesSupport();
+
+ return;
+}
diff --git a/Core/CPU/CpuPei.c b/Core/CPU/CpuPei.c
new file mode 100644
index 0000000..901171b
--- /dev/null
+++ b/Core/CPU/CpuPei.c
@@ -0,0 +1,936 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.c 9 8/05/14 2:21a Crystallee $
+//
+// $Revision: 9 $
+//
+// $Date: 8/05/14 2:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.c $
+//
+// 9 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 8 7/16/14 4:12a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add WbMemMap and UcMemMap vectors size to prevent
+// accessing out of bound.
+//
+// 7 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 6 6/25/14 2:15a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Add APIC version information in CpuInfoHob
+//
+// 5 6/13/14 2:22a Davidhsieh
+// [TAG] EIP173454
+// [Category] Improvement
+// [Description] Add TSEG address and size in CpuInfoHob
+//
+// 4 9/05/12 1:40a Davidhsieh
+// Rename PEI_IFFS_TRANSITION_START_PPI_GUID to
+// PEI_RAPID_START_TRANSITION_START_PPI_GUID
+//
+// 3 3/16/12 3:11a Davidhsieh
+// Setup items create for CPU RC policy
+//
+// 2 3/09/12 2:13a Davidhsieh
+// Create BIST data
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPei.c
+//
+// Description:
+// This file is the main CPU PEI component file. This component utilizes
+// CPU I/O & PCI CFG PPI to publish early CPU Init PPI which can be used
+// by NB PEI to load itself. Also this file contains a CPU init routine
+// to be executed in permanent memory present environment. This is handled
+// by issuing a notifyPPI on permanent memory PPI.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "cpu.h"
+#include "AmiCspLibInc.h"
+#include <AmiPeiLib.h>
+#include <core\PeiHob.h>
+#include <token.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include "CpuPei.h"
+
+#define EFI_HT_BIST_HOB_GUID \
+ { \
+ 0xbe644001, 0xe7d4, 0x48b1, 0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7 \
+ }
+
+typedef struct _CPU_BIST_HOB {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+ UINT32 ApicId;
+ UINT32 BIST;
+} CPU_BIST_HOB;
+
+// Setup GUID variables for installing, locating and notifying PPIs
+EFI_GUID gPeiCachePpiGuid = PEI_CACHE_PPI_GUID;
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+EFI_GUID gAmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+EFI_GUID gEfiPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+EFI_GUID gAmiInternaluCodeHobGuid = AMI_INTERNAL_UCODE_HOB_GUID;
+EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+EFI_GUID gPeiRapidStartTransitionStartPpiGuid = PEI_RAPID_START_TRANSITION_START_PPI_GUID;
+//EFI_GUID gCacheInstallGuid = EFI_CACHE_INSTALL_PPI_GUID;
+EFI_GUID gAmiStatusCodeCpuBistDataGuid = AMI_STATUS_CODE_CPU_BIST_DATA_GUID;
+EFI_GUID gEfiHtBistHobGuid = EFI_HT_BIST_HOB_GUID;
+
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+);
+
+EFI_PEI_NOTIFY_DESCRIPTOR CpuNotifyDescs = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ NotifyAtPeiEnd
+};
+
+/*EFI_PEI_PPI_DESCRIPTOR CacheInstallPpi[] = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCacheInstallGuid,
+ NULL
+};*/
+
+EFI_PEI_PPI_DESCRIPTOR IffsTransitionStartPpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), \
+ &gPeiRapidStartTransitionStartPpiGuid,
+ NULL
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReportBistStatusCodes
+//
+// Description: Report the BIST Status Code.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ReportBistStatusCodes(IN EFI_PEI_SERVICES **PeiServices, IN CPUINFO_HOB *CpuInfoHob, IN UINT32 NumCpus)
+{
+ UINT32 i;
+ AMI_STATUS_CODE_CPU_BIST_DATA BistData;
+
+ BistData.DataHeader.HeaderSize = sizeof(EFI_STATUS_CODE_DATA);
+ BistData.DataHeader.Size = sizeof(UINT32);
+ MemCpy(&BistData.DataHeader.Type, &gAmiStatusCodeCpuBistDataGuid, sizeof(EFI_GUID));
+
+ for (i = 0; i < NumCpus; ++i) {
+ if (CpuInfoHob->Cpuinfo[i].BIST != 0) {
+ PEI_TRACE((-1, PeiServices, "CpuInfo[%x].BIST = %x \n", i, CpuInfoHob->Cpuinfo[i].BIST));
+ BistData.Bist = CpuInfoHob->Cpuinfo[i].BIST;
+
+ (*PeiServices)->ReportStatusCode(
+ PeiServices,
+ EFI_ERROR_CODE| EFI_ERROR_MAJOR,
+ PEI_CPU_SELF_TEST_FAILED,
+ CpuInfoHob->Cpuinfo[i].ApicId,
+ NULL,
+ (EFI_STATUS_CODE_DATA*)&BistData
+ );
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateCpuHobWithDefaults
+//
+// Description: Create CPU Hob and fill in default data.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINT8 NumCpus
+//
+// Output:
+// CPUINFO_HOB *
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CPUINFO_HOB * CreateCpuHobWithDefaults(EFI_PEI_SERVICES **PeiServices, UINT8 NumCpus)
+{
+ CPUINFO_HOB *CpuinfoHob;
+ EFI_STATUS Status;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT8 i;
+ VOID *FirstHob;
+ CPU_BIST_HOB *SecBistHob;
+
+ //Create hob for storing Cpu Data
+ Status = (**PeiServices).CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ //NOTE: sizeof(CPUINFO_HOB) already includes size of one CPUINFO structure
+ sizeof(CPUINFO_HOB) + (NumCpus - 1) * sizeof(CPUINFO),
+ &CpuinfoHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ CpuinfoHob->EfiHobGuidType.Name = gAmiCpuinfoHobGuid;
+ CpuinfoHob->CpuCount = NumCpus;
+ CpuinfoHob->NodeCount = NUMBER_CPU_SOCKETS;
+ CpuinfoHob->CacheLineSize = 64;
+
+ CpuinfoHob->TsegAddress = NBGetTsegBase();
+ CpuinfoHob->TsegSize = TSEG_SIZE;
+
+
+ for(i = 0; i < NumCpus; ++i) {
+ CpuinfoHob->Cpuinfo[i].Valid = FALSE;
+ CpuinfoHob->Cpuinfo[i].Disabled = FALSE;
+ CpuinfoHob->Cpuinfo[i].BIST = 0;
+ CpuinfoHob->Cpuinfo[i].ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ }
+//Save BSP features to CpuinfoHob
+ CPULib_CpuID(0x01, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ CpuinfoHob->CpuFeatures.FeatureEcx = RegEcx;
+ CpuinfoHob->CpuFeatures.FeatureEdx = RegEdx;
+
+ CPULib_CpuID(0x80000001, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ CpuinfoHob->CpuFeatures.ExtFeatureEax = RegEax;
+ CpuinfoHob->CpuFeatures.ExtFeatureEbx = RegEbx;
+ CpuinfoHob->CpuFeatures.ExtFeatureEcx = RegEcx;
+ CpuinfoHob->CpuFeatures.ExtFeatureEdx = RegEdx;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ (VOID*)SecBistHob = FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &SecBistHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)SecBistHob)->Name, &gEfiHtBistHobGuid) == 0) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ CpuinfoHob->Cpuinfo[SecBistHob->ApicId].BIST = SecBistHob->BIST;
+ }
+
+ return CpuinfoHob;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: UpdateOrCreateCpuHob
+//
+// Description: Finds or Create Cpu Hob and initialize it.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UpdateOrCreateCpuHob(EFI_PEI_SERVICES **PeiServices)
+{
+ VOID *FirstHob;
+ EFI_HOB_CPU *CpuHob;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ EFI_STATUS Status;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ CpuHob = (EFI_HOB_CPU*) FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &CpuHob);
+ if (EFI_ERROR(Status)) {
+ Status = (**PeiServices).CreateHob(PeiServices,
+ EFI_HOB_TYPE_CPU,
+ sizeof(CpuHob),
+ &CpuHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ CpuHob->SizeOfMemorySpace = 0xff;
+ MemSet(CpuHob->Reserved, 6, 0);
+ }
+
+ CPULib_CpuID(0x80000008, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ RegEax &= 0xff;
+ if (RegEax < CpuHob->SizeOfMemorySpace) CpuHob->SizeOfMemorySpace = RegEax;
+ CpuHob->SizeOfIoSpace = 16;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NotifyAtPeiEnd
+//
+// Description: According to resource descriptor HOBs to config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor
+// IN VOID *Ppi
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+)
+{
+ EFI_STATUS Status;
+ PEI_CACHE_PPI *CachePpi;
+ UINT64 MaxMemoryLength;
+ EFI_BOOT_MODE BootMode;
+
+#if MTRR_POLICY == 1
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT64 Above4GMemoryLength = 0;
+ MEMORY_MAP WbMemMap[12]; //Memory map of wb regions.
+ MEMORY_MAP UcMemMap[12]; //Memory map of uc regions.
+ UINTN i;
+#endif
+ //
+ //Get bootmode
+ //
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ PEI_TRACE((-1, PeiServices, "CPUPEI Get boot mode in end of PEI\n"));
+
+ if (BootMode == BOOT_ON_S3_RESUME){
+ PEI_TRACE((-1, PeiServices, "CPUPEI boot mode is S3 in end of PEI\n"));
+ //Trigger SWSMI to save CPU fixed & varible MTRRs
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_RESTORE_MSR);
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_S3_RESTORE_MSR_FROM_SDL);
+ }else{
+ //
+ // Load Cache PPI
+ //
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCachePpiGuid,
+ 0,
+ NULL,
+ &CachePpi
+ ) ;
+ ASSERT_PEI_ERROR (PeiServices, Status);
+#if MTRR_POLICY == 1
+ //if MTRR_POLICY = 1, init MTRR above4G here
+ Above4GMemoryLength = 0;
+ (*PeiServices)->GetHobList(PeiServices, &Hob.Raw);
+ //Get above 4G memory length
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
+ ) {
+ if (Hob.ResourceDescriptor->PhysicalStart >= SIZE_4G
+ && Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ Above4GMemoryLength += (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ //
+ // Program the MTRR for above 4G memory range if it exist
+ // or just disable cache flash range
+ //
+ if (Above4GMemoryLength > 0) {
+ Status = InitMtrrPolicy1(PeiServices, WbMemMap, UcMemMap, Above4GMemoryLength);
+ if(EFI_ERROR(Status))
+ Status = InitMtrrPolicy2(PeiServices, WbMemMap, UcMemMap, Above4GMemoryLength);
+
+ //If cache map init successful, start program MTRR
+ if(!EFI_ERROR(Status)){
+ CachePpi->ResetCache(
+ PeiServices,
+ CachePpi);
+ //WB region start first
+ for(i = 0; i < 10 ;i++){
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ WbMemMap[i].Base,
+ WbMemMap[i].Len,
+ EfiCacheTypeWriteBack);
+ if(WbMemMap[i + 1].Len == 0) break;
+ }
+ //UC region start
+ if(UcMemMap[0].Len != 0){
+ for(i = 0; i < 10 ;i++){
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ UcMemMap[i].Base,
+ UcMemMap[i].Len,
+ EfiCacheTypeUncacheable);
+ if(UcMemMap[i + 1].Len == 0) break;
+ }
+ }
+ //
+ // Programm fix MTRRs WB from 0 to A0000
+ //
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ 0,
+ 640*1024,
+ EfiCacheTypeWriteBack );
+ } else{ //Get MTRR setting fail, still need disable cache flash range
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+ }
+ } else{ // if (Above4GMemoryLength > 0)
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+ }
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+#else
+ //
+ // MTRR for above 4G memory range is already done at this point,
+ // only disable cache flash range is required
+ //
+
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+#endif
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: SetupCache
+//
+// Description: According to resource descriptor HOBs to config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetupCache ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_BOOT_MODE BootMode)
+{
+ EFI_STATUS Status;
+ PEI_CACHE_PPI *CachePpi;
+ UINT64 MemoryLength;
+ UINT64 MemoryLengthUc;
+ UINT64 MaxMemoryLength;
+ UINT64 CurrentBaseAddress;
+ UINT64 Above4GMemoryLength;
+ UINT64 PowerTwo;
+ UINT64 PowerTwoEnd;
+ UINT8 MtrrCount = 0;
+#if MTRR_POLICY == 0
+ EFI_PEI_HOB_POINTERS Hob;
+#endif
+ //
+ // Load Cache PPI
+ //
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCachePpiGuid,
+ 0,
+ NULL,
+ &CachePpi
+ ) ;
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // Clear the CAR Settings
+ //
+ CachePpi->ResetCache(
+ PeiServices,
+ CachePpi
+ );
+
+
+ //
+ // Parse the HOB list and determine the amount of memory installed
+ // The first 1MB will be set until overridden by the CSM.
+ // The above 4G memory length will be calculated separately.
+ //
+
+ MemoryLength = SIZE_1M;
+ Above4GMemoryLength = 0;
+
+ MemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ PEI_TRACE((-1, PeiServices, "Memory Length below 4G= %lx.\n", MemoryLength));
+
+ //
+ // Record the current address
+ //
+ CurrentBaseAddress = 0;
+ //
+ // Set WB loop first
+ //
+
+ for (PowerTwo = SIZE_2G, PowerTwoEnd = SIZE_64M; PowerTwo >= PowerTwoEnd; PowerTwo = Shr64 (PowerTwo, 1)) {
+ if (MemoryLength >= PowerTwo && MtrrCount < 8) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", PowerTwo, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, PowerTwo, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ CurrentBaseAddress += PowerTwo;
+ MemoryLength -= PowerTwo;
+ }
+ }
+ //
+ // Get Max Address for WB/UC
+ //
+ if (MemoryLength == GetPowerOfTwo64 (MemoryLength)) {
+ MaxMemoryLength = MemoryLength;
+ } else {
+ MaxMemoryLength = GetPowerOfTwo64 (Shl64 (MemoryLength, 1));
+ }
+ //
+ // Set the MAX memory range as WB
+ //
+ if (MaxMemoryLength != 0 && MtrrCount < 8) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", MaxMemoryLength, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, MaxMemoryLength, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ }
+ //
+ // Start Setting UC here
+ //
+ while (MaxMemoryLength != MemoryLength) {
+ if (MtrrCount == 8) break;
+ MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);
+ PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx.\n", MemoryLengthUc, CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc));
+ CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc,
+ MemoryLengthUc,
+ EfiCacheTypeUncacheable
+ );
+ MtrrCount++;
+ MaxMemoryLength -= MemoryLengthUc;
+ }
+
+#if MTRR_POLICY == 0
+ //
+ // Program the MTRR for above 4G memory range
+ // if MTRR_POLICY = 1, program the MTRR for above 4G memory range at end of PEI
+ //
+ if (BootMode != BOOT_ON_S3_RESUME){
+ (*PeiServices)->GetHobList(PeiServices, &Hob.Raw);
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
+ ) {
+ //
+ // Calculate the memory above 4G
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= SIZE_4G
+ && Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ Above4GMemoryLength += (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ }
+ PEI_TRACE((-1, PeiServices, "Memory Length Above 4G= %lx.\n", Above4GMemoryLength));
+ if (Above4GMemoryLength > 0) {
+ CurrentBaseAddress = SIZE_4G;
+ while (Above4GMemoryLength >= SIZE_4G) {
+ if (MtrrCount == 10) break;
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", SIZE_4G, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, SIZE_4G, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ Above4GMemoryLength -= SIZE_4G;
+ CurrentBaseAddress += SIZE_4G;
+ }
+ //
+ // Set WB loop first
+ //
+ for (PowerTwo = SIZE_2G, PowerTwoEnd = SIZE_256M; PowerTwo >= PowerTwoEnd; PowerTwo = Shr64 (PowerTwo, 1)) {
+ if (MtrrCount == 10) break;
+ if (Above4GMemoryLength >= PowerTwo) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", PowerTwo, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, PowerTwo, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ CurrentBaseAddress += PowerTwo;
+ Above4GMemoryLength -= PowerTwo;
+ }
+ }
+ //
+ // Get Max Address for WB/UC
+ //
+ if (Above4GMemoryLength == GetPowerOfTwo64 (Above4GMemoryLength)) {
+ MaxMemoryLength = Above4GMemoryLength;
+ } else {
+ MaxMemoryLength = GetPowerOfTwo64 (Shl64(Above4GMemoryLength, 1));
+ }
+ //
+ // Set the MAX memory range as WB
+ //
+ if (MaxMemoryLength != 0 && MtrrCount < 10) {
+ //PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", MaxMemoryLength, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, MaxMemoryLength, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ }
+ //
+ // Start Setting UC here
+ //
+ while (MaxMemoryLength != Above4GMemoryLength) {
+ if (MtrrCount == 10) break;
+ MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - Above4GMemoryLength);
+ if (MtrrCount == 9 && (MaxMemoryLength - Above4GMemoryLength) != MemoryLengthUc) {
+ MemoryLengthUc = Shl64 (MemoryLengthUc, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx.\n", MemoryLengthUc, CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc));
+ CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (CurrentBaseAddress+ MaxMemoryLength - MemoryLengthUc),
+ MemoryLengthUc,
+ EfiCacheTypeUncacheable
+ );
+ MtrrCount++;
+ MaxMemoryLength -= MemoryLengthUc;
+ }
+ }
+#endif
+ //
+ // Programm fix MTRRs WB from 0 to A0000
+ //
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08x at %09x.\n", 640*1024, 0));
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ 0,
+ 640*1024,
+ EfiCacheTypeWriteBack
+ );
+
+#if PEI_CACHE_FLASH_ENABLED
+ //
+ // Cache Flash Area
+ //
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeWriteProtected
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Flash Area Caching Error!!\n"));
+#endif
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+
+ //Call back to disable caching flash at end of PEI.
+ (*PeiServices)->NotifyPpi(
+ PeiServices,
+ &CpuNotifyDescs
+ );
+ //
+ // Install EFI_CACHE_INSTALL_PPI_GUID to indicate memory and CPU cache are initialzed.
+ //
+ /*Status = (*PeiServices)->InstallPpi (
+ PeiServices,
+ CacheInstallPpi);
+ ASSERT_PEI_ERROR(PeiServices, Status);*/
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiEntry
+//
+// Description: AMI CPU PEI driver entry
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+ CPUINFO_HOB *CpuinfoHob;
+ UINT32 NumCpus;
+ BOOLEAN X2ApicEnabled = FALSE;
+ BOOLEAN Serialize = FALSE;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ VOID *MicrocodeAddr = NULL;
+ UINT32 MicrocodeSize = 0;
+ EFI_PHYSICAL_ADDRESS MicrocodeBuffer;
+ AMI_INTERNAL_UCODE_HOB *uCodeHob;
+ UINT32 Tseg = (UINT32)NBGetTsegBase();
+ SMM_HOB *SmmHob;
+ UINT32 SmmBspBase;
+ UINT32 SmmCpuBase;
+ UINT32 SmmBase;
+ UINT32 LargestSmmBase;
+ UINT32 MaxCpusBeforeOverlap;
+ UINT32 BeforeOverlapCount;
+ UINT32 NextUnoverlapSmmBase;
+ UINT32 i;
+
+ PEI_PROGRESS_CODE(PeiServices, PEI_CPU_INIT);
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices, &gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ SetupCache(PeiServices, BootMode);
+ UpdateOrCreateCpuHob(PeiServices);
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, \
+ &IffsTransitionStartPpiDescriptor);
+
+ //After initialized, APs are in holding loop until halted.
+ NumCpus = (UINT32)((UINT8)ReadMsr(MSR_CORE_THREAD_COUNT));
+
+ PEI_TRACE((-1, PeiServices, "Cpu Pei - number of Cpus %x\n",NumCpus ));
+ CpuinfoHob = CreateCpuHobWithDefaults(PeiServices, NumCpus);
+
+ CpuinfoHob->BspNo = 0;
+
+ ReportBistStatusCodes(PeiServices, CpuinfoHob, NumCpus);
+ //Create Smm Hob
+ Status = (*PeiServices)->CreateHob(
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(SMM_HOB)+ (NumCpus - 1) * sizeof(VOID*),
+ &SmmHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(&SmmHob->EfiHobGuidType.Name, &gSmmHobGuid, sizeof(EFI_GUID));
+
+ SmmHob->Tseg = Tseg;
+ SmmHob->TsegLength = TSEG_SIZE;
+ PEI_ASSERT(PeiServices, (SmmHob->Tseg & 0x7fffff)==0); //Must be 8MB boundary.
+ PEI_ASSERT(PeiServices, TSEG_SIZE >= 0x800000); //Must be >= 8MB.
+
+ SmmHob->IedStart = Tseg + TSEG_SIZE - IED_SIZE;
+ SmmHob->IedSize = IED_SIZE;
+
+ SmmHob->NumCpus = NumCpus;
+ SmmHob->Bsp = 0;
+
+ SmmBspBase = (UINTN)Tseg - 0x8000; //Get bottom of TSEG - 0x8000
+ SmmBase = SmmBspBase + MAX_SMM_SAVE_STATE_SIZE;
+
+ MaxCpusBeforeOverlap = 0x8000 / MAX_SMM_SAVE_STATE_SIZE - 1;
+ BeforeOverlapCount = 0;
+ NextUnoverlapSmmBase = (UINTN)Tseg - 0x8000 + 0x10000 - 2 * MAX_SMM_SAVE_STATE_SIZE;
+ LargestSmmBase = 0;
+
+ for (i = 0; i < NumCpus; ++i)
+ {
+ if (i == SmmHob->Bsp)
+ {
+ SmmCpuBase = SmmBspBase;
+ if (SmmCpuBase >= ((UINTN)Tseg - 0x8000)) ++BeforeOverlapCount; //Only increment count if BSP in TSEG.
+ }
+ else
+ {
+ SmmCpuBase = SmmBase;
+ ++BeforeOverlapCount;
+ if (BeforeOverlapCount < MaxCpusBeforeOverlap)
+ {
+ SmmBase += MAX_SMM_SAVE_STATE_SIZE;
+ }
+ else
+ {
+ SmmBase = NextUnoverlapSmmBase;
+ NextUnoverlapSmmBase += 0x10000 - 2 * MAX_SMM_SAVE_STATE_SIZE;
+ BeforeOverlapCount = 0;
+ }
+ }
+
+ SmmHob->SmmBase[i] = SmmCpuBase;
+
+ if (SmmCpuBase > LargestSmmBase) LargestSmmBase = SmmCpuBase;
+ }
+
+ if (LargestSmmBase < 0xC0000)
+ SmmHob->ManagedMemStart = Tseg;
+ else
+ SmmHob->ManagedMemStart = LargestSmmBase + 0x10000; //+ 0x10000 = end of save state.
+
+ SmmHob->ManagedMemSize = Tseg + TSEG_SIZE - SmmHob->ManagedMemStart;
+ SmmHob->ManagedMemSize -= SmmHob->IedSize;
+
+ PEI_TRACE((-1, PeiServices, "TSEG Base %x\n", SmmHob->Tseg));
+ PEI_TRACE((-1, PeiServices, "TSEG Size %x\n", SmmHob->TsegLength));
+ PEI_TRACE((-1, PeiServices, "ManagedMemStart %x\n", SmmHob->ManagedMemStart));
+
+ if (BootMode != BOOT_ON_S3_RESUME){
+ //Copy CPU microcode from ROM to RAM, when flash ragne is still cached
+ //and create hob to record the microcode address
+ //Create CPU microcode HOB
+ MicrocodeAddr = CPULib_FindMicrocode();
+
+ if(MicrocodeAddr != NULL){
+ PEI_TRACE((-1, PeiServices, "Cpu uCode ID - %x\n",((MICROCODE_HEADER*)MicrocodeAddr)->CpuSignature ));
+ MicrocodeSize = ((MICROCODE_HEADER*)MicrocodeAddr)->TotalSize;
+
+ Status = (*PeiServices)->AllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (MicrocodeSize),
+ &MicrocodeBuffer );
+ if(!EFI_ERROR(Status)){
+ // Copy Microcode from ROM to RAM
+ (*PeiServices)->CopyMem (
+ (VOID*)MicrocodeBuffer,
+ (VOID*)MicrocodeAddr,
+ (UINTN)MicrocodeSize );
+
+ Status = (*PeiServices)->CreateHob(
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(AMI_INTERNAL_UCODE_HOB),
+ &uCodeHob );
+ if (!EFI_ERROR(Status)){
+ MemCpy(&uCodeHob->EfiHobGuidType.Name, &gAmiInternaluCodeHobGuid, sizeof(EFI_GUID));
+ uCodeHob->uCodeAddr = (UINT32)MicrocodeBuffer;
+ }
+ }
+ }
+ }
+
+ CpuPeiMiscFuncs(PeiServices, ReadOnlyVariable, BootMode);
+
+ return EFI_SUCCESS;
+
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuPei.dxs b/Core/CPU/CpuPei.dxs
new file mode 100644
index 0000000..ba054a4
--- /dev/null
+++ b/Core/CPU/CpuPei.dxs
@@ -0,0 +1,65 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.dxs 1 2/07/12 3:58a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:58a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.dxs $
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CPUPEI.dxs
+//
+// Description: Dependency expression for CPU PEI component.
+// Currently it is dependent on the CPU IO & PCI CFG PPI.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <pei.h>
+#include <ppi\CpuIo.h>
+#include <ppi\PciCfg.h>
+#include <Ppi\ReadOnlyVariable.h>
+
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI AND
+ EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ EFI_PEI_CPU_IO_PPI_INSTALLED_GUID AND
+ EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID AND
+ EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuPei.h b/Core/CPU/CpuPei.h
new file mode 100644
index 0000000..b004293
--- /dev/null
+++ b/Core/CPU/CpuPei.h
@@ -0,0 +1,206 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.h 4 8/05/14 2:21a Crystallee $
+//
+// $Revision: 4 $
+//
+// $Date: 8/05/14 2:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.h $
+//
+// 4 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 3 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 2 9/05/12 1:40a Davidhsieh
+// Rename PEI_IFFS_TRANSITION_START_PPI_GUID to
+// PEI_RAPID_START_TRANSITION_START_PPI_GUID
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuPei.h
+//
+// Description: Cpu PEI header file.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_PEI_H__
+#define __CPU_PEI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IED_SIZE 0x400000
+#define VariableMtrrCount 10
+
+#define SIZE_1M 0x100000
+#define SIZE_64M 0x4000000
+#define SIZE_128M 0x8000000
+#define SIZE_256M 0x10000000
+#define SIZE_512M 0x20000000
+#define SIZE_1G 0x40000000
+#define SIZE_2G 0x80000000
+#define SIZE_4G 0x100000000
+#define SIZE_8G 0x200000000
+#define SIZE_16G 0x400000000
+
+//Chagned in IvyBridge RC 0.8
+//#define PEI_CACHE_PPI_GUID \
+// {0xc153205a, 0xe898, 0x4c24, 0x86, 0x89, 0xa4, 0xb4, 0xbc, 0xc5, 0xc8, 0xa2}
+#define PEI_CACHE_PPI_GUID \
+ {0x9be4bc2, 0x790e, 0x4dea, 0x8b, 0xdc, 0x38, 0x5, 0x16, 0x98, 0x39, 0x44}
+
+#define AMI_INTERNAL_UCODE_HOB_GUID \
+ {0x94567c6f, 0xf7a9, 0x4229, 0x13, 0x30, 0xfe, 0x11, 0xcc, 0xab, 0x3a, 0x11}
+
+#define PEI_RAPID_START_TRANSITION_START_PPI_GUID \
+ { \
+ 0xde8f2878, 0x36d5, 0x498e, 0xba, 0x59, 0x16, 0x8c, 0x26, 0x47, 0xb3, 0x35 \
+ }
+
+typedef struct {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ UINT32 uCodeAddr;
+} AMI_INTERNAL_UCODE_HOB;
+
+typedef enum _EFI_MEMORY_CACHE_TYPE
+{
+ EfiCacheTypeUncacheable = 0,
+ EfiCacheTypeWriteCombining= 1,
+ EfiCacheTypeReserved2 = 2,
+ EfiCacheTypeReserved3 = 3,
+ EfiCacheTypeWriteThrough = 4,
+ EfiCacheTypeWriteProtected= 5,
+ EfiCacheTypeWriteBack = 6,
+ EfiCacheTypeMaximumType = 7
+} EFI_MEMORY_CACHE_TYPE;
+
+
+typedef struct _PEI_CACHE_PPI PEI_CACHE_PPI;
+
+//
+// *******************************************************
+// PEI_SET_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SET_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This,
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
+ );
+
+//
+// *******************************************************
+// PEI_RESET_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_RESET_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This
+ );
+
+//
+// *******************************************************
+// PEI_ACTIVATE_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_ACTIVATE_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This
+ );
+
+//
+// *******************************************************
+// PEI_CACHE_PPI
+// *******************************************************
+//
+typedef struct _PEI_CACHE_PPI {
+ PEI_SET_CACHE_PPI SetCache;
+ PEI_RESET_CACHE_PPI ResetCache;
+ PEI_ACTIVATE_CACHE_PPI ActivateCache;
+} PEI_CACHE_PPI;
+
+typedef struct {
+ UINT64 Base;
+ UINT64 Len;
+} MEMORY_MAP;
+
+EFI_STATUS InitMtrrPolicy1 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+);
+
+EFI_STATUS InitMtrrPolicy2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+);
+
+VOID CpuPeiMiscFuncs (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuPeiBeforeMem.c b/Core/CPU/CpuPeiBeforeMem.c
new file mode 100644
index 0000000..9647874
--- /dev/null
+++ b/Core/CPU/CpuPeiBeforeMem.c
@@ -0,0 +1,1268 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiBeforeMem.c 8 10/16/13 4:03a Crystallee $
+//
+// $Revision: 8 $
+//
+// $Date: 10/16/13 4:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiBeforeMem.c $
+//
+// 8 10/16/13 4:03a Crystallee
+// [TAG] EIP138897
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Locate BIST ppi will fail after disable CAR.
+// [RootCause] All SEC PPIs must be reinstalled outside of SEC,
+// otherwise they will be lost when CAR is no longer used.
+// [Solution] Reinstall BIST PPI outside of SEC.
+//
+// 7 6/03/13 12:04a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description]
+// 1. Fix PLL setting is invalid once PEG/DMI ratio is 1:1.
+// 2. Modify IA core ratio minimun value. Use "max non turbo ratio(MSR
+// CEh)" instead of "power on turbo default value".
+//
+// 6 4/08/13 12:04a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description] Limit CPU boot performance at Non-Turbo speed when add
+// XTU.
+//
+// 5 2/07/13 4:13a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] Add:
+// 1. Support IA core and Ring voltage offset negative in OC mailbox.
+// 2. Add Filter PLL function, please change
+// "HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT" token if need to use this
+// function.
+//
+// Fixed:
+// 1. TDP Time Window is now programmed to 8 seconds by default.
+// 2. When cold reset, re-enabling FIVR faults and SVID control.
+// 3. Initialize OC mailbox for each boot.
+//
+// 4 12/20/12 10:15a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 3 12/20/12 9:58a Hsingyingchung
+// [TAG] EIP107712
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Change core ratio limit is not effective for oc cpu.
+// [RootCause] The IA core max ratio in mailbox is not same as active
+// one core ratio limit in MSR 0x1AD
+// [Solution] Update the IA core max ratio in mailbox according to
+// active one core ratio limit in XTU setting data
+//
+// 2 11/23/12 2:09a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPeiBeforeMem.c
+//
+// Description: This file is the main contains Cpu code that must execute
+// before memory.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Pei.h>
+#include <AmiPeiLib.h>
+#include "CPU.h"
+#include "AmiCspLibInc.h"
+#include "token.h"
+#include <Ppi\AmiEarlyBistPpi.h>
+
+#if PERF_TUNE_SUPPORT == 1
+ #include <Ppi\PerfTunePpi.h>
+ #include <PerfTune.h>
+ #include "Ppi\CpuPlatformPolicy\CpuPlatformPolicy.h"
+ #include <Setup.h>
+ #include <PPI\Stall.h>
+ #include "Board\EM\PerfTune\PerfTuneCpuSetup.h"
+ typedef struct{
+ UINT8 MeFirmwareInfo;
+ UINT32 MeMajor;
+ UINT32 MeMinor;
+ UINT32 MeHotFix;
+ UINT32 MeBuildNo;
+ } ME_INFO_SETUP_DATA;
+#define AMI_CPU_INTERNAL_ME_FW_VERSION_GUID \
+ {0x9b875aac, 0x36ec, 0x4550, 0xa4, 0xae, 0x86, 0xc8, 0x4e, 0x96, 0x76, 0x7e}
+EFI_GUID gAmiCpuMEFwVerGuid = AMI_CPU_INTERNAL_ME_FW_VERSION_GUID;
+#endif
+
+
+#if PERF_TUNE_SUPPORT == 1
+
+static EFI_GUID gPeiCpuPlatformPolicyGuid = PEI_CPU_PLATFORM_POLICY_PPI_GUID;
+static EFI_GUID gPerfTunePpiGuid = PERF_TUNE_PPI_GUID;
+static EFI_GUID gWdtPpiGuid = PERF_TUNE_WDT_PPI_GUID;
+static EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+static EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+
+EFI_STATUS CpuPeiPolicyNotify(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+
+// PPI that are notified
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCpuPlatformPolicyGuid,
+ CpuPeiPolicyNotify
+ }
+};
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PLLFilterFunction
+//
+// Description: Filter PLL setting High(3.2GHz) or lower(1.6GHz)
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PLLFilterFunction (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData
+)
+{
+ UINT8 GpioSel;
+ UINT8 GpRstSel;
+ UINT32 RcbaAddress;
+ UINT8 PmCFG2;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+
+ //
+ // Set GPIO_USE_SEL[8] to `0'
+ //
+ GpioSel = READ_IO8(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL); // 0x00
+ GpioSel = GpioSel & 0x7F;
+ WriteIo8 ((GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL), GpioSel);
+
+ //
+ // Set GP_RST_SEL[8] is `1'
+ //
+ GpRstSel = READ_IO8 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1); // 0x60
+ GpRstSel |= BIT8;
+ WriteIo8 ((GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1), GpRstSel);
+
+ //
+ //
+ // Set PCH_RCRB_PM_CFG 0x3318 bit 5
+ RcbaAddress = (READ_PCI32 (00, 0x1F, 0x0, 0xF0)) & 0xFFFFF000;
+ PmCFG2 = READ_MEM8 (RcbaAddress + 0x3318);
+ if (SettingData->FilterPLLFrequency){
+ PmCFG2 |= BIT5; //Bit5 set 1
+ }else{
+ PmCFG2 &= 0xDF; //Bit5 set 0
+ }
+ WRITE_MEM8 (RcbaAddress + 0x3318, PmCFG2);
+
+
+ //
+ // Issue a CF9h with a power cycle
+ //
+ //Let WDT know this is a normal reset.
+ (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ WdtPpi->AllowKnowReset(PeiServices);
+ IoWrite8 (0xCF9,0x0e);
+ EFI_DEADLOOP();
+
+ return EFI_SUCCESS;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OverrideNonTurboRatio
+//
+// Description: Override CPU NonTurbo Ratio Maximum value
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// UINT8 ProcessorMul
+// CPU_CONFIG_PPI *CpuConfig
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OverrideNonTurboRatio(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 ProcessorMul,
+ IN CPU_CONFIG_PPI *CpuConfig
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ CPU_RATIO_LIMIT_DATA CpuRatioLimitData;
+ UINTN VarSize = sizeof(CPU_RATIO_LIMIT_DATA);
+
+ PEI_TRACE((-1, PeiServices, "OverrideNonTurboRatio start!!\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ NULL,
+ &VarSize,
+ &CpuRatioLimitData
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ //check if cpuratio in PurfTuneCPUSetup is not default Max Non Turbo Ratio.
+ if((UINT8)(ProcessorMul & 0xFF) != ((CpuRatioLimitData.MaxNonTurboRatio) & 0xFF)){
+ CpuConfig->CpuRatioOverride = CPU_FEATURE_ENABLE;
+ CpuConfig->CpuRatio = (UINT8)(ProcessorMul & 0xFF);
+ }
+
+ PEI_TRACE((-1, PeiServices, "OverrideNonTurboRatio end!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PEGDMIRatio
+//
+// Description: Modify PEG/DMI Ratio for CPU
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PEGDMIRatio(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 PciAddress, PciRegData;
+ UINT64 PCIEPLLRatio, MsrData;
+ EFI_BOOT_MODE BootMode = (EFI_BOOT_MODE)-1;
+ UINT8 Ratio = 0xFF;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ UINTN VarSize = sizeof(SETUP_DATA);
+ SETUP_DATA SetupData;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+ ME_INFO_SETUP_DATA mMeInfoSetupData;
+ UINTN MeVarSize = sizeof(ME_INFO_SETUP_DATA);
+
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio start!!\n"));
+
+ //is SBPLL desired
+ //MSR 0x61E , bit2: SBPLL(1) or LCPLL(0).
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"Setup",
+ &SetupGuid,
+ NULL,
+ &VarSize,
+ &SetupData
+ );
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, " Get SetupData fail!!\n"));
+ return Status;
+ }
+ MsrData = ReadMsr(0x61E);
+ PEI_TRACE((-1, PeiServices, "SetupData.LcSbSelect: %x !!\n",SetupData.LcSbSelect));
+ MsrData = (SetupData.LcSbSelect)? MsrData | BIT2 : (MsrData & ~(BIT2));
+ WriteMsr(0x61E,MsrData);
+
+ //read ICC PEG/DMI ratio setting
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x60;
+ IoWrite32(0x0cf8,PciAddress);
+ PciRegData = IoRead32(0x0cfc);
+
+ //B0:D22:F0, FWstatus3[2:0]
+ //000b = 5/5, 1 - Used when BCLK at 100MHz
+ //001b = 5/4, 1.25 - Used when BCLK around 125MHz
+ //010b = 5/3, 1.66 - Used when BCLK around 166MHz
+ //011b = 5/2, 2.5 - Used when BCLK around 250MHz
+ //100b~111b = Reserved
+ switch(SettingData->PEGDMIRatio){
+ case 100: Ratio = 0x0; break;
+ case 125: Ratio = 0x1; break;
+ case 167: Ratio = 0x2; break;
+ case 250: Ratio = 0x3; break;
+ }
+ if((PciRegData & 0x3) == (ReadMsr(0x61E)& 0x3) || (PciRegData & 0x3) != Ratio){
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio suspend!!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ //read CMOS and check if need to set bootmode = BOOT_ON_S3_RESUME
+ IoWrite8(0x70,0x50);
+ PEI_TRACE((-1, PeiServices, "S3 resume request: %x\n",IoRead8(0x71)));
+ if(IoRead8(0x71) == 0xA5){
+ (*PeiServices)->SetBootMode(PeiServices, BOOT_ON_S3_RESUME); //restore BootMode after set BCLK over ratio and generate warm reset.
+ IoWrite8(0x71,0x5A); //clear scratch
+ }
+
+ PCIEPLLRatio = ReadMsr(0x61E) & ~(BIT0 | BIT1 | BIT3); //clear PCIE_Ratio & Long_Reset bit
+
+ //PCIE_Ratio bit
+ MsrData = 0;
+ switch(Ratio){
+ case 0x0: MsrData = 0; break;
+ case 0x1: MsrData = 0 | BIT0; break;
+ case 0x2: MsrData = 0 | BIT1; break;
+ case 0x3: MsrData = 0 | BIT0 | BIT1; break;
+ }
+ //long reset bit
+ MsrData |= BIT3;
+
+ PCIEPLLRatio |= MsrData;
+ WriteMsr(0x61E,PCIEPLLRatio);
+
+ //Record current BootMode for restore after warm reset
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME)
+ IoWrite8(0x71,0xA5);
+ PEI_TRACE((-1, PeiServices, "S3scratchpad value: %x\n",IoRead8(0x71)));
+
+ //Is Memory in Self refresh?(B0:D31:F0, REG:0xa2)
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x1f) << 11) | ((0x0) << 8) | 0xa0;
+ IoWrite32(0x0cf8,PciAddress);
+ PciRegData = IoRead32(0x0cfc);
+ PEI_TRACE((-1, PeiServices, "Read GEN_PMCON2 value: %x\n",PciRegData));
+ if(!((PciRegData >> 16) & BIT5)){ //is memory in self-refresh
+ //clear GEN_PMCON2 bit7(DRAM Initialization Bit)
+ IoWrite32(0x0cfc,PciRegData & ~(BIT7 << 16));
+ }
+
+ //Need to send ICC message to enable Ramp when ME Firmware build no. is above 1221.
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"MEFWVersion",
+ &gAmiCpuMEFwVerGuid,
+ NULL,
+ &MeVarSize,
+ &mMeInfoSetupData
+ );
+ if(!EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "ME FW Build No %d\n",mMeInfoSetupData.MeBuildNo));
+ if(mMeInfoSetupData.MeBuildNo >= 1221){
+ //Write a value of 0x60000001 to PCI 0:22:0 offset 0x4C.
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x4c;
+ IoWrite32(0x0cf8,PciAddress);
+ //Bits 31:28 - Message Type:
+ // 0x06 - ICC BIOS Message
+ //Bit 0 - BCLK Ramp Enable
+ // 0x01 - BCLK Ramp Enable
+ IoWrite32(0x0cfc,0x60000001);
+
+ //Wait for FW ACK by reading FWStatus PCI 0:22:0 offset 0x40 for ICC FW ACK
+ //type and success status.
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x40;
+ IoWrite32(0x0cf8,PciAddress);
+ //Bits 31:28 - Message Type:
+ // 0x06 - ICC BIOS Message
+ //Bits 27:25 - ICC BIOS Ack Data
+ // 0 - ICC Success
+ // 1 - ICC BIOS Request Failed
+ while((Shr64(IoRead32(0x0cfc),25) & 0x7) != 0){} //wait for BCLK Ramp Enable success
+ }
+ }
+ else
+ PEI_TRACE((-1, PeiServices, "Get Me Fw Version fail!!\n"));
+
+ //warm reset
+ PEI_TRACE((-1, PeiServices, "Warmreset!!\n"));
+ //Let WDT know this is a normal reset.
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ WdtPpi->AllowKnowReset(PeiServices);
+ IoWrite8 (0xCF9,0x06);
+ EFI_DEADLOOP();
+
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio end!!\n"));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnablePLLOverVoltage
+//
+// Description: Enable PLL over voltage for CPU
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// UINT8 NumOfCpuCore
+// UINT16 *pCoreRatioData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnablePLLOverVoltage(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 NumOfCpuCore,
+ IN UINT16 *pCoreRatioData
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID gAmiPllOvFlagHobGuid = AMI_PLL_OVER_VOTAGE_FLAG_HOB_GUID;
+ EFI_GUID gPeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID gAmiPllOvFlagDataGuid = gAmiPllOvFlagHobGuid;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ UINTN VarSize = sizeof(PLL_OV_FLAG_DATA);
+ PLL_OV_FLAG_DATA_HOB *PllOvFlagHob;
+ UINT16 i;
+ UINT8 *OriRatioLimit;
+
+ PEI_TRACE((-1, PeiServices, "EnablePLLOverVoltage Start\n"));
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(PLL_OV_FLAG_DATA_HOB),
+ &PllOvFlagHob);
+ if (EFI_ERROR(Status))return Status;
+
+ PllOvFlagHob->EfiHobGuidType.Name = gAmiPllOvFlagHobGuid;
+ OriRatioLimit = (UINT8*)&PllOvFlagHob->PllOvData.OriTurboRatio;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"PLLOvFlag",
+ &gAmiPllOvFlagDataGuid,
+ NULL,
+ &VarSize,
+ &PllOvFlagHob->PllOvData
+ );
+
+ if(!(EFI_ERROR(Status)) && (PllOvFlagHob->PllOvData.PLLOvFlag== 0x2)) return EFI_ALREADY_STARTED;
+
+ for(i = 0; i < sizeof(UINT64); i++){
+ if( i < NumOfCpuCore)
+ OriRatioLimit[i] = (UINT8)pCoreRatioData[i];
+ else
+ OriRatioLimit[i] = 0x00;
+
+ if( i < 3)
+ pCoreRatioData[i] = 0x06;
+ else
+ pCoreRatioData[i] = 0x00;
+ }
+
+ PllOvFlagHob->PllOvData.PLLOvFlag = 0x1;
+ WriteMsr(MSR_TURBO_RATIO_LIMIT,0x60606);
+
+ PEI_TRACE((-1, PeiServices, "EnablePLLOverVoltage End\n"));
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectOcConfig
+//
+// Description: Collect Overclocking Config data from MSR 0x150.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// OVERCLOCKING_CONFIG_HOB *OverclockConfig
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectOcConfig(
+ EFI_PEI_SERVICES **PeiServices,
+ OVERCLOCKING_CONFIG_DATA *OverclockConfig
+){
+ EFI_STATUS Status;
+ UINT64 MsrData;
+ UINT8 i;
+ PERF_TUNE_PPI *PerfTunePpi;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+
+ PEI_TRACE((-1, PeiServices, "Collect Overclocking config data(MSR 0x150) Start\n"));
+
+ OverclockConfig->OcSupport = 0;
+ OverclockConfig->IsPowerCycle = IsPowerCycle();
+ OverclockConfig->IsCpuRunDefault = TRUE;
+
+ //collect CPU overclocking config data
+ for(i=0;i<DOMAIN_MAX_NUM;++i){
+ //1. Overclocking Capability
+ MsrData = 0;
+ Status = GetOcCapability(i, &MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->OCCap[i].MaxOcRatioLimit = (UINT8)MsrData;
+ OverclockConfig->OCCap[i].RatioOcSupported = (MsrData & BIT8)?1:0;
+ OverclockConfig->OCCap[i].VoltageOverridesSupported = (MsrData & BIT9)?1:0;
+ OverclockConfig->OCCap[i].VoltageOffsetSupported = (MsrData & BIT10)?1:0;
+ if (!OverclockConfig->OcSupport)
+ OverclockConfig->OcSupport = OverclockConfig->OCCap[i].RatioOcSupported ||
+ OverclockConfig->OCCap[i].VoltageOverridesSupported||
+ OverclockConfig->OCCap[i].VoltageOffsetSupported ;
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "Domain %x GetOcCapability fail [0x%x]\n",i,Shr64(MsrData,32) & 0xFF));
+ }
+
+ //2. Overclocking Voltage/Frequency
+ MsrData = 0;
+ Status = GetVoltFreq(i, &MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->VFDef[i].MaxOcRatio = (UINT8)MsrData;
+ OverclockConfig->VFDef[i].VoltageTargetMode = (UINT8)(Shr64(MsrData,20) & 0x1);
+ OverclockConfig->VFDef[i].VoltageTarget = (UINT16)(Shr64(MsrData,8) & 0xFFF);
+ OverclockConfig->VFDef[i].VoltageOffset = (INT16)(Shr64(MsrData,21) & 0x7FF);
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "Domain %x GetVoltFreq fail [0x%x]\n",i,Shr64(MsrData,32) & 0xFF));
+ }
+ }
+ //3. SVID Config
+ MsrData = 0;
+ Status = GetSVIDConfig(&MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->SvidDisable = (MsrData & BIT31)?1:0;
+ OverclockConfig->SvidVoltageOverride = (UINT16)(MsrData & 0xFFF);
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "GetSVIDConfig fail [0x%x]\n",Shr64(MsrData,32) & 0xFF));
+ }
+
+ //4. Misc Global Config
+ MsrData = 0;
+ Status = GetFIVRConfig(&MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->FivrFaultsDisable = (MsrData & BIT0)?1:0;
+ OverclockConfig->FivrEfficiencyDisable = (MsrData & BIT1)?1:0;
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "GetMiscConfig fail [0x%x]\n",Shr64(MsrData,32) & 0xFF));
+ }
+
+ PEI_TRACE((-1, PeiServices, "Collect Overclocking config data(MSR 0x150) end\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ if ( !(PerfTunePpi->IsChangeCpu(PeiServices) && PerfTunePpi->IsRunDefault(PeiServices)) && !(WdtPpi->QueryTimeOut(PeiServices))){
+ OverclockConfig->IsCpuRunDefault = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitOcMailbox
+//
+// Description: Initialize Overclocking Config data.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitOcMailbox(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *FirstHob;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ PEI_TRACE((-1, PeiServices, "InitOcMailbox start!!\n"));
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Get OC config HOB fail!!\n"));
+ return Status;
+ }
+ OverclockData = &OverclockConfigHob->OverclockData;
+
+ //
+ // Initialize Overclocking Data
+ //
+ if(OverclockData->OCCap[IA].RatioOcSupported){
+ OverclockingConfig->CoreMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF;
+ }
+
+ if(OverclockData->OCCap[RING].RatioOcSupported){
+ OverclockingConfig->ClrMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF; // read core one max ratio limit
+ }
+
+ OverclockingConfig->SvidEnable = 1; // 1: Enable
+ OverclockingConfig->FivrFaultsEnable = 1; // 1: Enable
+ OverclockingConfig->FivrEfficiencyEnable = 1; // 1: Enable
+
+ OverclockingConfig->OcSupport = 1; // 0: Disable, 1: Enable
+
+ PEI_TRACE((-1, PeiServices, "InitOcMailbox End!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OverlockingConfigUpdate
+//
+// Description: Update Overclocking Config data.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+// OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OverlockingConfigUpdate(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData,
+ IN OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *FirstHob;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ PEI_TRACE((-1, PeiServices, "OverlockingConfigUpdate start!!\n"));
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Get OC config HOB fail!!\n"));
+ return Status;
+ }
+ OverclockData = &OverclockConfigHob->OverclockData;
+
+
+ //Overwrite OverclockingConfig data in Intel reference code
+ if(OverclockData->OcSupport){
+ //IA core
+ // Core Max overclocking turbo ratio
+ if(OverclockData->OCCap[IA].RatioOcSupported){
+ OverclockingConfig->CoreMaxOcTurboRatio = (SettingData->CoreRatioLimit1)?SettingData->CoreRatioLimit1:ReadMsr(0x1AD) & 0xFF;
+ if (SettingData->CoreRatioLimit1 < SettingData->ProcessorMul )
+ OverclockingConfig->CoreMaxOcTurboRatio = SettingData->ProcessorMul;
+ }
+
+ if(OverclockData->OCCap[IA].VoltageOverridesSupported){
+ // Voltage Mode, 0: Adaptive, 1: Override(Static)
+ OverclockingConfig->CoreVoltageMode = (UINT8)SettingData->IACoreVoltageMode;
+
+ if(SettingData->IACoreVoltageMode == 0x1){
+ // Override(Static) mode
+ OverclockingConfig->CoreVoltageOverride = SettingData->CPUVoltage;
+ if(SettingData->CPUVoltage == 0xFFFF)
+ OverclockingConfig->CoreVoltageOverride = 0;
+ OverclockingConfig->CoreExtraTurboVoltage = 0;
+ }
+ else{
+ // Adaptive mode
+ OverclockingConfig->CoreExtraTurboVoltage = SettingData->CPUVoltage;
+ if(SettingData->CPUVoltage == 0xFFFF)
+ OverclockingConfig->CoreExtraTurboVoltage = 0;
+ OverclockingConfig->CoreVoltageOverride = 0;
+ }
+ }
+
+ if(OverclockData->OCCap[IA].VoltageOffsetSupported){
+ if (SettingData->DynamicCPUVoltage >=0 && \
+ SettingData->DynamicCPUVoltage <= 999){
+ OverclockingConfig->CoreVoltageOffset = ~(1000 - SettingData->DynamicCPUVoltage) + 1;
+ }else if (SettingData->DynamicCPUVoltage >=1000 && \
+ SettingData->DynamicCPUVoltage <= 1998){
+ OverclockingConfig->CoreVoltageOffset = SettingData->DynamicCPUVoltage - 1000;
+ }
+
+ }
+
+ //RING
+ // Ring Max overclocking turbo ratio
+ if(OverclockData->OCCap[RING].RatioOcSupported){
+ if(SettingData->RingRatio){
+ OverclockingConfig->ClrMaxOcTurboRatio = SettingData->RingRatio;
+ }
+ else{
+ // first boot
+ OverclockingConfig->ClrMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF; // read core one max ratio limit
+ }
+ }
+
+ if(OverclockData->OCCap[RING].VoltageOverridesSupported){
+ // Voltage Mode, 0: Adaptive, 1: Override(Static)
+ OverclockingConfig->ClrVoltageMode = (UINT8)SettingData->RingVoltageMode;
+
+ if(SettingData->RingVoltageMode == 0x1){
+ // Override(Static) mode
+ OverclockingConfig->ClrVoltageOverride = SettingData->RingVoltageOverride;
+ if(SettingData->RingVoltageOverride == 0xFFFF)
+ OverclockingConfig->ClrVoltageOverride = 0;
+ OverclockingConfig->ClrExtraTurboVoltage = 0;
+ }
+ else{
+ // Adaptive mode
+ OverclockingConfig->ClrExtraTurboVoltage = SettingData->RingVoltageOverride;
+ if(SettingData->RingVoltageOverride == 0xFFFF)
+ OverclockingConfig->ClrExtraTurboVoltage = 0;
+ OverclockingConfig->ClrVoltageOverride = 0;
+ }
+ }
+
+ if(OverclockData->OCCap[RING].VoltageOffsetSupported){
+ if (SettingData->RingVoltageOffset >=0 && \
+ SettingData->RingVoltageOffset <= 999){
+ OverclockingConfig->ClrVoltageOffset = ~(1000 - SettingData->RingVoltageOffset) + 1;
+ }else if (SettingData->RingVoltageOffset >=1000 && \
+ SettingData->RingVoltageOffset <= 1998){
+ OverclockingConfig->ClrVoltageOffset = SettingData->RingVoltageOffset - 1000;
+ }
+ }
+
+ //SVID and FIVR
+ if(SettingData->DynamicSVIDControl != 0xFFFF)
+ OverclockingConfig->SvidEnable = (UINT8)(SettingData->DynamicSVIDControl); // 0: Disable, 1: Enable
+ if(OverclockData->IsPowerCycle)
+ OverclockingConfig->SvidEnable = 1; // When cold boot, reset to the default value '1'.
+ if(SettingData->DynamicSVIDControl != 0xFFFF && SettingData->SVIDVoltageOverride != 0xFFFF)
+ OverclockingConfig->SvidVoltageOverride = (SettingData->DynamicSVIDControl)? SettingData->SVIDVoltageOverride : 0; // External VR voltage override
+
+ if(SettingData->FIVRFaults != 0xFFFF)
+ OverclockingConfig->FivrFaultsEnable = (UINT8)(SettingData->FIVRFaults); // 0: Disable, 1: Enable
+ if(OverclockData->IsPowerCycle)
+ OverclockingConfig->FivrFaultsEnable = 1; // When cold boot, reset to the default value '1'.
+ if(SettingData->FIVREfficiencyManagenment != 0xFFFF)
+ OverclockingConfig->FivrEfficiencyEnable = (UINT8)(SettingData->FIVREfficiencyManagenment); // 0: Disable, 1: Enable
+
+ //Enable orDisable Reference code execute Cpu Overclocking Initialize(CpuOcInit).
+ OverclockingConfig->OcSupport = 1; // 0: Disable, 1: Enable
+ OverclockingConfig->BitReserved = 0;
+ }
+ PEI_TRACE((-1, PeiServices, "OverlockingConfigUpdate end!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiPolicyOverWrite
+//
+// Description: This function over writes the CPU PEI RC policy
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CpuPeiPolicyOverWrite (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+
+ //UINT8 MaxNonTurboRatio;
+ //UINT8 NumBinsSupport;
+ UINT8 CpuCores = NumCpuCores();
+ UINT16 i;
+ UINT16 Xtu_CoreRatioArray[6];
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ //UINT64 MsrData;
+
+ EFI_STATUS Status;
+ PEI_CPU_PLATFORM_POLICY_PPI *PeiCpuPolicyPpi;
+ //PPI_CPU_POWER_FEATURE_CONFIG *PeiCpuPowerFeatureConfig;
+ POWER_MGMT_CONFIG_PPI *PeiCpuPowerFeatureConfig;
+ PERF_TUNE_PPI *PerfTunePpi;
+ //PERF_TUNE_WDT_PPI *WdtPpi;
+ BIOS_SETTING_DATA SettingData;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+ CPU_RATIO_LIMIT_HOB *CpuRatioLimitHob;
+ CPU_RATIO_LIMIT_DATA *CpuRatioLimitData;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ SETUP_DATA SetupData;
+ UINTN VarSize = sizeof(SETUP_DATA);
+
+ PEI_TRACE((-1, PeiServices, "Start CPU PEI RC policy overwrite\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status)) return;
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"Setup",
+ &SetupGuid,
+ NULL,
+ &VarSize,
+ &SetupData
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCpuPlatformPolicyGuid,
+ 0,
+ NULL,
+ &PeiCpuPolicyPpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "Perfmorance tunning PPI located\n"));
+
+ // collect OcMailbox data
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(OVERCLOCKING_CONFIG_HOB),
+ &OverclockConfigHob);
+ if (EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Create OverclockConfigHob fail\n"));
+ return;
+ }
+ OverclockConfigHob->EfiHobGuidType.Name = gAmiOcConfigHobGuid;
+ OverclockData = &OverclockConfigHob->OverclockData;
+ CollectOcConfig(PeiServices,OverclockData);
+ InitOcMailbox(PeiServices,PeiCpuPolicyPpi->OverclockingConfig);
+
+ if(PerfTunePpi->IsChangeCpu(PeiServices)){
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(CPU_RATIO_LIMIT_HOB),
+ &CpuRatioLimitHob);
+ if (EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Create NonTurboRatioMax HOB fail\n"));
+ return;
+ }
+ CpuRatioLimitHob->EfiHobGuidType.Name = gAmiCpuRatioLimitHobGuid;
+ CpuRatioLimitData = &CpuRatioLimitHob->CpuRatioLimitData;
+ CpuRatioLimitData->MaxNonTurboRatio = (UINT8)(Shr64(ReadMsr(0x0ce), 8) & 0xFF);
+ CpuRatioLimitHob->IsChangeCpu = PerfTunePpi->IsChangeCpu(PeiServices);
+ }
+ /*
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "watch dogger timer PPI located\n"));
+ */
+ Status = PerfTunePpi->GetSettingData(
+ PeiServices,
+ &SettingData
+ );
+
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "Got Perfmorance tunning setting data\n"));
+
+ if(!((PerfTunePpi->IsChangeCpu(PeiServices) && PerfTunePpi->IsRunDefault(PeiServices)))){
+ //if(!(WdtPpi->QueryTimeOut(PeiServices))){
+
+ PEI_TRACE((-1, PeiServices, "ReConfig XE policy from XTU\n"));
+ //PeiCpuPowerFeatureConfig = PeiCpuPolicyPpi->PpiCpuPowerFeatureConfig;
+ PeiCpuPowerFeatureConfig = PeiCpuPolicyPpi->PowerMgmtConfig;
+ //PeiCpuPowerFeatureConfig->PrimaryPlaneCurrentLimit = (SettingData.IACoreCurrentMax & 0x1fff);
+ PeiCpuPowerFeatureConfig->VrCurrentLimit = (SettingData.PackageCurrentLimit & 0x1fff);
+ //PeiCpuPowerFeatureConfig->SecondaryPlaneCurrentLimit = (SettingData.IGFXCoreCurrentMax & 0x1fff);
+ PeiCpuPowerFeatureConfig->VrCurrentLimitLock = (!OverclockData->IsCpuRunDefault)? SetupData.PackageCurrentLock : CPU_FEATURE_DISABLE ;
+ // CPU boot with Maximum Non-Turbo speed.
+ PeiCpuPowerFeatureConfig->BootInLfm = CPU_FEATURE_DISABLE;
+
+ if (isXECoreRatioLimitSupported())
+ {
+ PEI_TRACE((-1, PeiServices, "XE part CPU found\n"));
+
+ PeiCpuPowerFeatureConfig->Xe = CPU_FEATURE_ENABLE;
+ Xtu_CoreRatioArray[0] = SettingData.CoreRatioLimit1;
+ Xtu_CoreRatioArray[1] = SettingData.CoreRatioLimit2;
+ Xtu_CoreRatioArray[2] = SettingData.CoreRatioLimit3;
+ Xtu_CoreRatioArray[3] = SettingData.CoreRatioLimit4;
+ Xtu_CoreRatioArray[4] = SettingData.CoreRatioLimit5;
+ Xtu_CoreRatioArray[5] = SettingData.CoreRatioLimit6;
+
+ for(i = 0; i < CpuCores; ++i)
+ if(SettingData.ProcessorMul > Xtu_CoreRatioArray[i])
+ Xtu_CoreRatioArray[i] = SettingData.ProcessorMul;
+
+ /*Force Runtime Turbo not suuport now
+ if (CpuSigNoVer == SANDY_BRIDGE && SettingData.RuntimeTurboEanble)
+ {
+ PEI_TRACE((-1, PeiServices, "SnadyBridge Runtime Turbo ratio change\n"));
+ MsrData = ReadMsr(MSR_FLEX_RATIO);
+ NumBinsSupport = (UINT8)((UINT32)MsrData >> 17) & 0x7;
+
+ //Read Max_Non turbo ratio.
+ MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ MaxNonTurboRatio = ((UINT32) MsrData >> MAX_NON_TURBO_RATIO_OFFSET) & MAX_NON_TURBO_RATIO_MASK;
+
+ MsrData = ReadMsr(MSR_TURBO_RATIO_LIMIT);
+ for(i = 0; i < CpuCores; i++)
+ {
+ if((NumBinsSupport > 0)&&(NumBinsSupport < 7))
+ {
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = MsrData & 0xff + NumBinsSupport;
+ } else {
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = 0x39;
+ }
+ MsrData = Shr64(MsrData, 8);
+ }
+
+ } else {*/
+ PEI_TRACE((-1, PeiServices, "CPU core ratio limit change\n"));
+ for(i = 0; i < CpuCores; i++){
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = (UINT8)(Xtu_CoreRatioArray[i]);
+ PEI_TRACE((-1, PeiServices, "XTU for %x core ratio limit = %x \n", (i + 1, Xtu_CoreRatioArray[i])));
+ }
+ //}
+
+ //PeiCpuPowerFeatureConfig->OverClockExtraVoltage = SettingData.MaxTurboModeCPUVoltage;
+
+ // Change Cpu Max Non-Tubro Ratio
+ if(SettingData.ProcessorMul != 0xFFFF){
+ Status = OverrideNonTurboRatio(PeiServices,SettingData.ProcessorMul,PeiCpuPolicyPpi->CpuConfig);
+ }
+ }
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ if(SettingData.FilterPLLFrequency != 0xFFFF){
+ UINT32 RcbaAdd;
+ UINT8 PmCFG;
+
+ RcbaAdd = (READ_PCI32 (00, 0x1F, 0x0, 0xF0)) & 0xFFFFF000;
+ PmCFG = READ_MEM8 (RcbaAdd + 0x3318);
+ if ( SettingData.FilterPLLFrequency != ( (PmCFG & BIT5) >> 5)){
+ PLLFilterFunction(PeiServices,&SettingData);
+ }
+ }
+#endif
+
+ // Change PEG/DMI Ratio
+ if(SettingData.PEGDMIRatio != 0xFFFF){
+ if(isBCLKRatioSuuported()){
+ PEGDMIRatio(PeiServices,&SettingData);
+ }
+ }
+ // Enable PLL Over Voltage feature
+ if(SettingData.CpuPllVoltageUnlockEnable == 0x1){
+ Status = EnablePLLOverVoltage(PeiServices,CpuCores,(UINT16*)Xtu_CoreRatioArray);
+ }
+
+ // Updata OC config data in CpuOcInit.c
+ Status = OverlockingConfigUpdate(PeiServices,&SettingData,PeiCpuPolicyPpi->OverclockingConfig);
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiPolicyNotify
+//
+// Description: CPU PEI pollicy PPI notify function
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor
+// VOID *NullPpi
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiPolicyNotify(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ CpuPeiPolicyOverWrite(PeiServices);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiXtuInitBeforeMem
+//
+// Description: CPU XTU init code in PEI phase
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiXtuInitBeforeMem(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+
+ EFI_STATUS Status;
+ PEI_CPU_PLATFORM_POLICY_PPI *PeiCpuPolicyPpi;
+
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiCpuPlatformPolicyGuid, 0, NULL, &PeiCpuPolicyPpi);
+ if (Status == EFI_SUCCESS) {
+ CpuPeiPolicyOverWrite(PeiServices);
+ } else {
+ Status = (*PeiServices)->NotifyPpi(PeiServices, mNotifyList);
+ }
+
+ return Status;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReinstallSecPpis
+//
+// Description:
+// Reinstall PPIs from stack because stack will be lost when cache-as-ram is turned off.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//Sec Core Descriptors on stack will be lost when cache-as-ram is turned off.
+VOID ReinstallSecPpis(IN EFI_PEI_SERVICES **PeiServices)
+{
+ EFI_STATUS Status;
+ EFI_GUID gAmiEarlyBistGuid = AMI_EARLY_BIST_PPI_GUID;
+
+ AMI_EARLY_BIST_PPI *OldAmiBistPpi;
+ AMI_EARLY_BIST_PPI *NewAmiBistPpi;
+
+ EFI_PEI_PPI_DESCRIPTOR *OldPpiDesc;
+ EFI_PEI_PPI_DESCRIPTOR *NewPpiDesc;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gAmiEarlyBistGuid,
+ 0,&OldPpiDesc,
+ &OldAmiBistPpi
+ );
+ if (!EFI_ERROR(Status)) {
+
+ //Create new PPI in allocated memory because the location in stack from Sec Core
+ //will not be available after memory.
+ Status = (*PeiServices)->AllocatePool(PeiServices,
+ sizeof(AMI_EARLY_BIST_PPI) + (OldAmiBistPpi->NumBists - 1) * sizeof(CPU_BIST),
+ &NewAmiBistPpi
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(
+ NewAmiBistPpi,
+ OldAmiBistPpi,
+ sizeof(AMI_EARLY_BIST_PPI) + (OldAmiBistPpi->NumBists - 1) * sizeof(CPU_BIST)
+ );
+
+ //Create new Descriptor
+ Status = (*PeiServices)->AllocatePool(PeiServices,
+ sizeof(EFI_PEI_PPI_DESCRIPTOR),
+ &NewPpiDesc
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(NewPpiDesc, OldPpiDesc, sizeof(EFI_PEI_PPI_DESCRIPTOR));
+ NewPpiDesc->Ppi = NewAmiBistPpi;
+
+ (*PeiServices)->ReInstallPpi(
+ PeiServices,
+ (EFI_PEI_PPI_DESCRIPTOR*)OldPpiDesc,
+ (EFI_PEI_PPI_DESCRIPTOR*)NewPpiDesc
+ );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiBeforeMemEntry
+//
+// Description: CPU PEI functions before memory ready
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuPeiBeforeMemEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+#if PERF_TUNE_SUPPORT == 1
+ EFI_STATUS Status;
+ Status = CpuPeiXtuInitBeforeMem(PeiServices);
+#endif
+
+ ReinstallSecPpis(PeiServices);
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuPeiFuncs.c b/Core/CPU/CpuPeiFuncs.c
new file mode 100644
index 0000000..c5bb238
--- /dev/null
+++ b/Core/CPU/CpuPeiFuncs.c
@@ -0,0 +1,1378 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiFuncs.c 10 8/06/14 11:57p Crystallee $
+//
+// $Revision: 10 $
+//
+// $Date: 8/06/14 11:57p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiFuncs.c $
+//
+// 10 8/06/14 11:57p Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add special case for saving MTRRs.
+//
+// 9 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 8 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 7 6/03/13 2:37a Hsingyingchung
+// [TAG] EIP123835
+// [Category] Spec Update
+// [Severity] Important
+// [Description] SBY Performance Tuning Guid rev. 1.1 update.
+//
+// 6 2/07/13 3:59a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] add PEI/DMI ratio control item.
+//
+// 5 12/20/12 10:09a Hsingyingchung
+// [TAG] EIP
+// [Category] Improvement
+// [Description] Remove mailbox item limit. Because mailbox item is not
+// be effected by turbo mode support or not.
+//
+// 4 11/23/12 2:10a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 3 10/25/12 4:01a Davidhsieh
+// Add ReadOnlyVariable.h file include
+//
+// 2 3/09/12 2:14a Davidhsieh
+// Use all variable MTRRs
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPeiFuncs.c
+//
+// Description:
+// This file is the main CPU PEI component file. This file provides
+// misc functions for CPU PEI drvier usage.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "cpu.h"
+#include "AmiCspLibInc.h"
+#include <AmiPeiLib.h>
+#include <core\PeiHob.h>
+#include <token.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include "CpuPei.h"
+#include "Setup.h"
+
+#if PERF_TUNE_SUPPORT == 1
+ #include <Ppi\PerfTunePpi.h>
+ #include <PerfTune.h>
+
+ //TODO: Update library and remove private structure.
+ typedef struct {
+ SETUP_DATA *SetupData;
+ } PRIVATE_CPU_SETUP_LIB;
+
+ EFI_GUID gAmiDddtPreFlagHobGuid = AMI_DDDT_PRESENT_FLAG_HOB_GUID;
+ EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+#endif
+
+#if MTRR_POLICY == 1
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitMtrrPolicy1
+//
+// Description: Config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN PEI_CACHE_PPI *CachePpi
+// IN UINT64 Above4GMemoryLength
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitMtrrPolicy1 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+)
+{
+
+ UINT64 TotalAbove4GMemoryLength = Above4GMemoryLength + SIZE_4G;
+ UINT64 RemainMemoryLength = TotalAbove4GMemoryLength - GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ UINT64 Below4GMemoryLength;
+ UINT64 MemoryLengthUc;
+ UINT64 CurrentBaseAddress;
+ UINT64 PowerTwo;
+ UINTN i, WbCount = 0, UcCount = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 NumOfOne = 0;
+
+ CurrentBaseAddress = 0;
+
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbCount++;
+ MtrrCount++;
+
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ //
+ // UC memory length below 4GB = 4GB - total memory length below 4GB
+ //
+ MemoryLengthUc = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (MemoryLengthUc);
+
+ for (PowerTwo = GetPowerOfTwo64 (MemoryLengthUc);
+ CurrentBaseAddress >= Below4GMemoryLength; PowerTwo = GetPowerOfTwo64 (MemoryLengthUc)) {
+
+ //PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %08lx.\n", PowerTwo, CurrentBaseAddress));
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = PowerTwo;
+ MemoryLengthUc -= PowerTwo;
+ CurrentBaseAddress -= GetPowerOfTwo64 (MemoryLengthUc);
+ UcCount++;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Calculate how many MTRRs needs if only use WB type
+ //
+ for (i = 0; i < 32; i++) {
+ if (Shr64(RemainMemoryLength, i) & 0x1 )
+ NumOfOne++;
+ }
+
+ //PEI_TRACE((-1, PeiServices, "Remain above 4G Memory Length = %08lx number of one = %x.\n", RemainMemoryLength, NumOfOne));
+
+ if (NumOfOne + MtrrCount < VariableMtrrCount){ //Use WB range is enough
+
+ CurrentBaseAddress = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ while(RemainMemoryLength)
+ {
+ PowerTwo = GetPowerOfTwo64 (RemainMemoryLength);
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = PowerTwo;
+ WbCount++;
+ CurrentBaseAddress += (UINT64)PowerTwo;
+ RemainMemoryLength -= (UINT64)PowerTwo;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+ } else{
+ //
+ // Use UC to overwrite WB memory
+ //
+ if ((RemainMemoryLength - GetPowerOfTwo64(RemainMemoryLength)) < SIZE_2G)
+ {
+ WbMap[WbCount].Base = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= WbMap[WbCount].Len;
+ WbCount++;
+ MtrrCount++;
+ WbMap[WbCount].Base = WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len;
+ WbMap[WbCount].Len = GetPowerOfTwo64(Shl64(RemainMemoryLength,1));
+
+ MemoryLengthUc = WbMap[WbCount].Len - RemainMemoryLength;
+ CurrentBaseAddress = (WbMap[WbCount].Base + WbMap[WbCount].Len) - GetPowerOfTwo64(MemoryLengthUc);
+ if ((WbMap[WbCount].Len + WbMap[WbCount - 1].Len) == GetPowerOfTwo64(WbMap[WbCount].Len + WbMap[WbCount - 1].Len))
+ {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+ } else {
+ WbCount++;
+ MtrrCount++;
+ }
+
+ } else{
+ WbMap[WbCount].Base = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbMap[WbCount].Len = GetPowerOfTwo64(Shl64(RemainMemoryLength,1));
+ if (WbMap[WbCount - 1].Len == WbMap[WbCount].Base){
+ // special case to save mtrr
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+ WbCount--;
+ MtrrCount--;
+ }
+
+ MemoryLengthUc = (WbMap[WbCount].Base + WbMap[WbCount].Len) - TotalAbove4GMemoryLength;
+ CurrentBaseAddress = (WbMap[WbCount].Base + WbMap[WbCount].Len) - GetPowerOfTwo64(MemoryLengthUc);
+ WbCount++;
+ MtrrCount++;
+ }
+ //PEI_TRACE((-1, PeiServices, "Above 4G UC Memory Length = %08lx base start at %08lx.\n", MemoryLengthUc, CurrentBaseAddress));
+ for (PowerTwo = GetPowerOfTwo64 (MemoryLengthUc);
+ CurrentBaseAddress >= TotalAbove4GMemoryLength; PowerTwo = GetPowerOfTwo64 (MemoryLengthUc)) {
+
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = PowerTwo;
+ MemoryLengthUc -= PowerTwo;
+ CurrentBaseAddress -= GetPowerOfTwo64 (MemoryLengthUc);
+ UcCount++;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy1 success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NumOfOne
+//
+// Description: Count how many of ones in the binary value.
+//
+// Input:
+// IN UINT64 InputValue - Needed count value.
+//
+// Output:
+// UINT8 - Number of one.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumOfOne(
+ IN UINT64 InputValue)
+{
+ UINT8 i, j;
+
+ for (i = 0, j = 0; i < 40; i++) {
+ if (Shr64(InputValue, i) & 0x1 )
+ j++;
+ if (Shr64(InputValue, i) == 0)
+ break;
+ }
+ return j;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitMtrrPolicy2
+//
+// Description: Config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN PEI_CACHE_PPI *CachePpi
+// IN UINT64 Above4GMemoryLength
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitMtrrPolicy2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+)
+{
+ UINT64 TotalMemoryLength = Above4GMemoryLength + SIZE_4G;
+ UINT64 RemainMemoryLength;
+ UINT64 Below4GMemoryLength;
+ UINTN i;
+ UINT8 WbMtrrCountBelow4G1 = 0;
+ UINT8 WbMtrrCountBelow4G2 = 0;
+ UINT8 UcMtrrCountBelow4G1 = 0;
+ UINT8 UcMtrrCountBelow4G2 = 0;
+ UINT8 WbMtrrCountAbove4G1 = 0;
+ UINT8 WbMtrrCountAbove4G2 = 0;
+ UINT8 UcMtrrCountAbove4G1 = 0;
+ UINT8 UcMtrrCountAbove4G2 = 0;
+ UINT8 UcMtrrCountAbove4G3 = 0;
+ UINT8 UcMtrrCountAbove4G4 = 0;
+ UINT8 MtrrCountRemainMemory1 = 0;
+ UINT8 MtrrCountRemainMemory2 = 0;
+ UINT8 MtrrCountRemainMemory3 = 0;
+ UINT64 MemoryLength;
+ UINT8 PolicyOneMtrrCount = 0;
+ UINT8 PolicyTwoMtrrCount = 0;
+ UINT8 PolicyThreeMtrrCount = 0;
+ UINT8 PolicyFourMtrrCount = 0;
+ UINT8 PolicyFiveMtrrCount = 0;
+ UINT8 PolicySixMtrrCount = 0;
+ BOOLEAN WbSpecialCase1 = 0;
+ BOOLEAN WbSpecialCase2 = 0;
+
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+
+ //First, we calculate how many MTRR we need in different situation.
+ //1. Calculating MTRR when only use wb type in below 4G memory
+ //There are two size of Below4GMemoryLength. One is NBGetTsegBase() + TSEG_SIZE, the other is NBGetTsegBase().
+ //Therefore we have two calculating method to calculate wb MTRR below 4G memory.
+ //A.When Below4GMemoryLength is NBGetTsegBase()
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ WbMtrrCountBelow4G1 = NumOfOne(Below4GMemoryLength);
+
+ //B.When Below4GMemoryLength is NBGetTsegBase() + TSEG_SIZE
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ WbMtrrCountBelow4G2 = NumOfOne(Below4GMemoryLength);
+
+ //2. Calculating MTRR when use wb type from 0 to 4G, then use uc type to overwrite 4G to Below4GMemoryLength.
+ //There are two size of Below4GMemoryLength. One is NBGetTsegBase() + TSEG_SIZE, the other is NBGetTsegBase().
+ //Therefore we have two calculating method to calculate uc MTRR below 4G memory.
+ //A.When Below4GMemoryLength is NBGetTsegBase()
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ UcMtrrCountBelow4G1 = NumOfOne(((UINT64)SIZE_4G - Below4GMemoryLength));
+
+ //B.When Below4GMemoryLength is NBGetTsegBase() + TSEG_SIZE
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ UcMtrrCountBelow4G2 = NumOfOne(((UINT64)SIZE_4G - Below4GMemoryLength));
+
+ //3. Calculating MTRR when Memory above 4G is larger then 4G.
+ //A.If it's larger then 4G, memory above 4G should minus SIZE_4G and MTRR count should add 1.
+ //Next, if remain memory above 4G still larger than SIZE_8G, remain memory minus SIZE_8G and MTRR count should add 1.
+ //Next, if remain memory above 4G still larger than SIZE_16G, remain memory minus SIZE_16G and MTRR count should add 1. And so on.
+ RemainMemoryLength = Above4GMemoryLength;
+ MemoryLength = SIZE_4G;
+ for (MtrrCountRemainMemory1 = 0; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+ MtrrCountRemainMemory1++;
+ RemainMemoryLength -= MemoryLength;
+ }
+
+ //B.Calculating MTRR when use wb type till remain memory is smaller then 2G
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ for (MtrrCountRemainMemory2 = 0; RemainMemoryLength >= SIZE_2G;) {
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ MtrrCountRemainMemory2++;
+ RemainMemoryLength -= MemoryLength;
+ }
+
+ //C.Calculating MTRR when only use wb type in remain memory
+ WbMtrrCountAbove4G1 = NumOfOne(RemainMemoryLength) + MtrrCountRemainMemory2;
+
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting. This case only occur in Policy two.
+ if ((MtrrCountRemainMemory2 != 0) && (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1) == MemoryLength))
+ WbSpecialCase1 = 0;
+ else
+ WbSpecialCase1 = 1;
+
+ //D.Calculating MTRR when use uc type to overwrite wb type.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G2 = NumOfOne(RemainMemoryLength);
+
+ //4. Calculating MTRR when use uc type to overwrite wb type above 4G memory, there are two calculating methods.
+ //A.Set wb type from 4G to shl(PowerOfTwo64(TotalMemoryLength),1),
+ //then use uc to overwrite overflow wb memory.
+ RemainMemoryLength = TotalMemoryLength - Shl64(SIZE_4G , MtrrCountRemainMemory1);
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G1 = NumOfOne(RemainMemoryLength);
+
+ //B.Set wb type from 0 to shl(PowerOfTwo64(TotalMemoryLength), 1),
+ //then use uc to overwrite overflow wb memory.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (TotalMemoryLength), 1)) - TotalMemoryLength;
+ UcMtrrCountAbove4G3 = NumOfOne(RemainMemoryLength);
+
+ //5. Calculating MTRR when (TotalMemoryLength) minus PowerOfTwo64(TotalMemoryLength) is larger then 2G.
+ //A. Calculating MTRR when use wb type till remain memory is smaller then 2G
+ RemainMemoryLength = TotalMemoryLength - GetPowerOfTwo64(TotalMemoryLength);
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ for (MtrrCountRemainMemory3 = 0; RemainMemoryLength >= SIZE_2G;) {
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ MtrrCountRemainMemory3++;
+ RemainMemoryLength -= MemoryLength;
+ }
+ //B.Calculating MTRR when use wb type in Remain memory
+ WbMtrrCountAbove4G2 = NumOfOne(RemainMemoryLength) + MtrrCountRemainMemory3;
+
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting. This case only occur in Policy five.
+ if ((MtrrCountRemainMemory3 != 0) && (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1) == MemoryLength))
+ WbSpecialCase2 = 0;
+ else
+ WbSpecialCase2 = 1;
+
+ //C.Calculating MTRR when use uc type to overwrite wb type.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G4 = NumOfOne(RemainMemoryLength);
+
+ //Second, Calculating MTRR for each setting MTRR policy.
+ //Policy 1:Only use wb type from 0 to Below4GMemoryLength, and 4G to TotalMemoryLength.
+ //
+ // _______ TotalMemoryLength
+ // |Wb Set |
+ // |-------| 4G
+ // |Uc Ori |
+ // |-------| Below4GMemoryLength
+ // |Wb Set |
+ // |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyOneMtrrCount = WbMtrrCountBelow4G1 + WbMtrrCountAbove4G1 + MtrrCountRemainMemory1;
+ else
+ PolicyOneMtrrCount = WbMtrrCountBelow4G2 + WbMtrrCountAbove4G1 + MtrrCountRemainMemory1;
+
+ //Policy 2:First, Use wb type from 0 to Below4GMemoryLength. Use wb type from 4G to 8G, 8G to 16G, and so on.
+ // Second, if remain memory larger then 2G , use wb type till remain memory samller then 2G. last, set wb type to shl(RemainMemory, 1).
+ // Third, use uc type from shl(RemainMemory, 1) to TotalMemoryLength.
+ // first Second third
+ // |-------| |-------| shl(RemainMemory, 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |-------| 4G |-------| 4G
+ // |Uc Ori | |Same |
+ // |-------| Below4GMemoryLength |as |
+ // |Wb Set | |first |
+ // |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyTwoMtrrCount = WbMtrrCountBelow4G1 + MtrrCountRemainMemory1 + MtrrCountRemainMemory2 + WbSpecialCase1 + UcMtrrCountAbove4G2;
+ else
+ PolicyTwoMtrrCount = WbMtrrCountBelow4G2 + MtrrCountRemainMemory1 + MtrrCountRemainMemory2 + WbSpecialCase1 + UcMtrrCountAbove4G2;
+
+ //Policy 3: First, Use wb type from 0 to Below4GMemoryLength. Use wb type from 4G to 8G, 8G to 16G, and so on.
+ // Second, set wb type to shl(RemainMemory, 1).
+ // Third, use uc type form shl(RemainMemory, 1) to TotalMemoryLength;
+ // first Second third
+ // |-------| shl(PowerOfTwo64(TotalMemoryLength), 1) |-------| shl(PowerOfTwo64(TotalMemoryLength), 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |-------| 4G |-------| 4G
+ // |Uc Ori | |Same |
+ // |-------| Below4GMemoryLength |as |
+ // |Wb Set | |first |
+ // |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyThreeMtrrCount = WbMtrrCountBelow4G1 + MtrrCountRemainMemory1 + 1 + UcMtrrCountAbove4G1;
+ else
+ PolicyThreeMtrrCount = WbMtrrCountBelow4G2 + MtrrCountRemainMemory1 + 1 + UcMtrrCountAbove4G1;
+
+ //Policy 4: First, use wb type from 0 to PowerOfTwo64(TotalMemoryLength).
+ // Second, use uc type from 4G to Below4GMemoryLength.
+ // Third, use wb type from PowerOfTwo64(TotalMemoryLength) to TotalMemoryLength.
+ // first second and third
+ // |--------| PowerOfTwo64(TotalMemoryLength) _______ TotalMemoryLength
+ // | | |Wb Set |
+ // |Wb Set | |-------| PowerOfTwo64(TotalMemoryLength)
+ // |ALL | | |
+ // | | |-------| 4G
+ // | | |Uc Set |
+ // | | |-------| Below4GMemoryLength
+ // |________| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicyFourMtrrCount = 1 + UcMtrrCountBelow4G1 + WbMtrrCountAbove4G2;
+ else
+ PolicyFourMtrrCount = 1 + UcMtrrCountBelow4G2 + WbMtrrCountAbove4G2;
+
+ //Policy 5: First, use wb type from 0 to PowerOfTwo64(TotalMemoryLength).
+ // Second, use uc type from 4G to Below4GMemoryLength.
+ // Third, remain memory will be (TotalMemoryLength - PowerOfTwo64(TotalMemoryLength)) use wb type\
+ // from PowerOfTwo64(TotalMemoryLength) to shl(RemainMemory, 1).
+ // Four, use uc type from shl(RemainMemory, 1) to TotalMemoryLength.
+ // first second and third Four
+ // |--------| PowerOfTwo64(TotalMemoryLength) ------- shl(RemainMemory, 1) ------- shl(RemainMemory, 1)
+ // | | |_______| TotalMemoryLength |Uc Set |
+ // |Wb Set | |Wb Set | |_______| TotalMemoryLength
+ // |ALL | |-------| PowerOfTwo64(TotalMemoryLength) | |
+ // | | |-------| 4G |Same |
+ // | | |Uc Set | |as |
+ // | | |-------| Below4GMemoryLength |before |
+ // |________| 0 |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicyFiveMtrrCount = 1 + UcMtrrCountBelow4G1 + MtrrCountRemainMemory3 + WbSpecialCase2 + UcMtrrCountAbove4G4;
+ else
+ PolicyFiveMtrrCount = 1 + UcMtrrCountBelow4G2 + MtrrCountRemainMemory3 + WbSpecialCase2 + UcMtrrCountAbove4G4;
+
+ //Policy 6:First, use wb type to shl(PowerOfTwo64(TotalMemoryLength), 1).
+ // Second, use uc type from 4G to Below4GMemoryLength and
+ // Uc type from shl(PowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength.
+ // first second
+ // |--------| shl(PowerOfTwo64(TotalMemoryLength), 1) |-------| shl(PowerOfTwo64(TotalMemoryLength), 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |ALL | | |
+ // | | |-------| 4G
+ // | | |Uc Set |
+ // | | |-------| Below4GMemoryLength
+ // |________| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicySixMtrrCount = 1 + UcMtrrCountBelow4G1 + UcMtrrCountAbove4G3;
+ else
+ PolicySixMtrrCount = 1 + UcMtrrCountBelow4G2 + UcMtrrCountAbove4G3;
+
+// PEI_TRACE((-1, PeiServices, "WbMtrrCountBelow4G1 = %d, WbMtrrCountBelow4G2 = %d.\n", WbMtrrCountBelow4G1, WbMtrrCountBelow4G2));
+// PEI_TRACE((-1, PeiServices, "UcMtrrCountBelow4G1 = %d, UcMtrrCountBelow4G2 = %d.\n", UcMtrrCountBelow4G1, UcMtrrCountBelow4G2));
+// PEI_TRACE((-1, PeiServices, "WbMtrrCountAbove4G1 = %d, WbMtrrCountAbove4G2= %d, UcMtrrCountAbove4G1 = %d.\n", WbMtrrCountAbove4G1, WbMtrrCountAbove4G2, UcMtrrCountAbove4G1));
+// PEI_TRACE((-1, PeiServices, "UcMtrrCountAbove4G2 = %d, UcMtrrCountAbove4G3 = %d, UcMtrrCountAbove4G4= %d.\n", UcMtrrCountAbove4G2, UcMtrrCountAbove4G3, UcMtrrCountAbove4G4));
+// PEI_TRACE((-1, PeiServices, "WbSpecialCase1 = %d, WbSpecialCase2 = %d.\n", WbSpecialCase1, WbSpecialCase2));
+// PEI_TRACE((-1, PeiServices, "MtrrCountRemainMemory1 = %d, MtrrCountRemainMemory2 = %d, MtrrCountRemainMemory3 = %d.\n", MtrrCountRemainMemory1, MtrrCountRemainMemory2, MtrrCountRemainMemory3));
+// PEI_TRACE((-1, PeiServices, "PolicyOneMtrrCount = %d, PolicyTwoMtrrCount = %d, PolicyThreeMtrrCount = %d.\n", PolicyOneMtrrCount, PolicyTwoMtrrCount, PolicyThreeMtrrCount));
+// PEI_TRACE((-1, PeiServices, "PolicyFourMtrrCount = %d, PolicyFiveMtrrCount = %d, PolicySixMtrrCount = %d.\n", PolicyFourMtrrCount, PolicyFiveMtrrCount, PolicySixMtrrCount));
+// PEI_TRACE((-1, PeiServices, "TsegBase = 0x%8lX, Above4GMemoryLength = 0x%8lX.\n", (UINT64)NBGetTsegBase(), Above4GMemoryLength));
+
+ //Policy one
+ if (PolicyOneMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G. And so on.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, set RemainMemoryLength to wb type.
+ if (Status == EFI_SUCCESS) {
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy one success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Two
+ if (PolicyTwoMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G. And so on.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, if remain memory larger than 2G, set wb type till remain memory smaller than 2G.
+ if (Status == EFI_SUCCESS) {
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength >= SIZE_2G; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+ }
+
+ //5. Set a wb type from CurrentBaseAddress to shl(PowerOfTwo64(RemainMemoryLength), 1)
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting.
+ if (((WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len) == WbMap[WbCount].Base) &&
+ (GetPowerOfTwo64(WbMap[WbCount - 1].Base) > WbMap[WbCount - 1].Len) &&
+ (WbMap[WbCount - 1].Len == WbMap[WbCount].Len)) {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount - 1].Len, WbMap[WbCount - 1].Base, MtrrCount - 1));
+ }
+ else {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount].Len, CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ }
+
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+
+ //6.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength, overwrite wb type.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy two success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Three
+ if (PolicyThreeMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, set wb type from 4G to Shl64(GetPowerOfTwo64(RemainMemoryLength), 1).
+ RemainMemoryLength = TotalMemoryLength - CurrentBaseAddress;
+ if (Status == EFI_SUCCESS) {
+ if (RemainMemoryLength > 0) {
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", Shl64(GetPowerOfTwo64(RemainMemoryLength), 1), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ }
+ }
+
+ //5.Next, set uc type from Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) to RemainMemoryLength
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy three success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Four
+ if (PolicyFourMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ RemainMemoryLength = TotalMemoryLength;
+
+ //2.Set GetPowerOfTwo64(RemainMemoryLength) to wb type.
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", GetPowerOfTwo64(RemainMemoryLength), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= GetPowerOfTwo64(RemainMemoryLength);
+
+ //3.Next, use wb type from CurrentBaseAddress to TotalMemoryLength.
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress += MemoryLength;
+ }
+ }
+
+ //4.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy four success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Five
+ if (PolicyFiveMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ RemainMemoryLength = TotalMemoryLength;
+
+ //2.Set GetPowerOfTwo64(RemainMemoryLength) to wb type.
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", GetPowerOfTwo64(RemainMemoryLength), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= GetPowerOfTwo64(RemainMemoryLength);
+
+ //3.Next, use wb type from CurrentBaseAddress till remain memory is smaller 2G.
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength >= SIZE_2G; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress += MemoryLength;
+ }
+ }
+
+ //4. Set a wb type from CurrentBaseAddress to shl(PowerOfTwo64(RemainMemoryLength), 1)
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting.
+ if (((WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len) == WbMap[WbCount].Base) &&
+ (GetPowerOfTwo64(WbMap[WbCount - 1].Base) > WbMap[WbCount - 1].Len) &&
+ (WbMap[WbCount - 1].Len == WbMap[WbCount].Len)) {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount - 1].Len, WbMap[WbCount - 1].Base, MtrrCount - 1));
+ }
+ else {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount].Len, CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ }
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+
+ //5.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength, overwrite wb type.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ //6.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy five success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Six
+ if (PolicySixMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ //2.Set wb type from 0 to Shl64(GetPowerOfTwo64(TotalMemoryLength), 1).
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(TotalMemoryLength), 1);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", Shl64(GetPowerOfTwo64(TotalMemoryLength), 1), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(TotalMemoryLength), 1);
+
+ //3.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) - TotalMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ //4.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy six success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+ PEI_TRACE((-1, PeiServices, "Set MTRR status = EFI_OUT_OF_RESOURCES\n"));
+ return EFI_OUT_OF_RESOURCES;
+}
+#endif
+
+#if PERF_TUNE_SUPPORT == 1
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiIntelXtuDataInit
+//
+// Description:
+// Interl XTU utility data initialize in PEI phase
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiIntelXtuDataInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+ EFI_STATUS Status;
+ BIOS_SETTING_DATA SettingData;
+ EFI_GUID PerfTunePpiGuid = PERF_TUNE_PPI_GUID;
+ EFI_GUID WdtPpiGuid = PERF_TUNE_WDT_PPI_GUID;
+ PERF_TUNE_PPI *PerfTunePpi;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+ DDDT_PRESENT_FLAG_HOB *DddtPreFlagHob;
+ VOID *FirstHob;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT8 i;
+ UINT8 CpuCores = NumCpuCores();
+ UINT8 NumOcBins = 0;
+ UINT8 CpuImptype[] = {BIOS_1_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_2_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_3_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_4_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_5_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_6_CORE_RATIO_IMPLEMENTATION };
+
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ if (CpuSigNoVer != IVY_BRIDGE)
+ NumOcBins = (UINT8)((UINT32)(ReadMsr(MSR_FLEX_RATIO)) >> 17) & 0x7;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ DddtPreFlagHob = (DDDT_PRESENT_FLAG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &DddtPreFlagHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)DddtPreFlagHob)->Name, &gAmiDddtPreFlagHobGuid) == 0) {
+ break;
+ }
+ }
+
+ if(!EFI_ERROR(Status)){
+ //iGfx Core Current Max Dddt Flag set to 1 or 0
+ //if((DddtPreFlagHob->PresentFlag[BIOS_GRAPHICS_TURBO_RATIO_LIMIT_IMPLEMENTATION] == 0)||\
+ // (DddtPreFlagHob->PresentFlag[BIOS_GRAPHICS_CORE_VOLTAGE_IMPLEMENTATION] == 0))
+ // DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 0;
+ //else
+ // DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 1;
+ DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 0; //disable IGFX current MAX
+
+ //if Cpu is partial unlock or full unlock then turbo Core ratio dddt should not build.
+ PEI_TRACE((-1, PeiServices, "CPU PEI XTU data init CpuCores = %x\n", CpuCores));
+ for (i = 0; i < sizeof(CpuImptype); i++){
+ if(CpuCores < (i + 1)){
+ DddtPreFlagHob->PresentFlag[CpuImptype[i]] = 0;
+ }
+ }
+
+ //Force Runtime Turbo disable
+ if (NumOcBins)
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_ENABLE_IMPLEMENTATION] = 1;
+ else
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_ENABLE_IMPLEMENTATION] = 0;
+
+ //Overclocking Core Ratio Limit disable
+ if (!isXECoreRatioLimitSupported()){
+ DddtPreFlagHob->PresentFlag[BIOS_1_CORE_RATIO_IMPLEMENTATION] = 0;//One-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_2_CORE_RATIO_IMPLEMENTATION] = 0;//Two-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_3_CORE_RATIO_IMPLEMENTATION] = 0;//Three-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_4_CORE_RATIO_IMPLEMENTATION] = 0;//Four-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_5_CORE_RATIO_IMPLEMENTATION] = 0;//Five-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_6_CORE_RATIO_IMPLEMENTATION] = 0;//Six-core Flag
+ }
+
+ //Package Power Limit disable
+ // Skus that support Config TDP are not able to change power limit(MSR 0x610) in real time.
+ if (!isXETdcTdpLimitSupported() || (Shr64(ReadMsr(MSR_PLATFORM_INFO), 32) & (BIT1 | BIT2)) ){
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_IMPLEMENTATION] = 0; //Short TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_IMPLEMENTATION] = 0; //Extended TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION] = 0; //Short TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION] = 0; //Package TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION] = 0; //Package TDP Time Window Flag
+ }
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_MAX_TURBO_MODE_CPU_VOLTAGE_IMPLEMENTATION] = 0;
+
+ //if cpu not support turbo mode, disable TDP, TDC, extend tdp, short tdp and all core ratio DDD table creation.
+ if(!isTurboModeSupported()){
+ DddtPreFlagHob->PresentFlag[BIOS_TURBO_ENABLE_IMPLEMENTATION] = 0; //Turbo Eanble Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDC_VALUE_IMPLEMENTATION] = 0; //TDC Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDP_VALUE_IMPLEMENTATION] = 0; //TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_1_CORE_RATIO_IMPLEMENTATION] = 0; //One-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_2_CORE_RATIO_IMPLEMENTATION] = 0; //Two-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_3_CORE_RATIO_IMPLEMENTATION] = 0; //Three-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_4_CORE_RATIO_IMPLEMENTATION] = 0; //Four-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_5_CORE_RATIO_IMPLEMENTATION] = 0; //Five-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_6_CORE_RATIO_IMPLEMENTATION] = 0; //Six-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_IMPLEMENTATION] = 0; //Short TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_IMPLEMENTATION] = 0; //Extended TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION] = 0; //Short TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0; //Runtime Turbo Overwride Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION] = 0; //Internal PLL overvoltage Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION] = 0; //Package TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION] = 0; //Package TDP Time Window Flag
+ /*
+ DddtPreFlagHob->PresentFlag[BIOS_OVERCLOCKING_ENABLE_IMPLEMENTATION] = 0; //Overclocking Lock Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Mode Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Offset Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_RATIO_IMPLEMENTATION] = 0; //Malibox: RING Ratio Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0; //Malibox: RING Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION] = 0; //Malibox: RING Voltage Mode Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION] = 0; //Malibox: RING Voltage Offset Flag
+ DddtPreFlagHob->PresentFlag[BIOS_DYNAMIC_SVID_CONTROL_IMPLEMENTATION] = 0; //Malibox: SVID Control Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SVID_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0; //Malibox: SVID Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_FIVR_FAULTS_IMPLEMENTATION] = 0; //Malibox: FIVR Faults Flag
+ DddtPreFlagHob->PresentFlag[BIOS_FIVR_EFFICIENCY_MANAGEMENT_IMPLEMENTATION] = 0; //Malibox: FIVR Efficiency Management Flag
+ */
+ }
+
+ if(!(isFullUnlockCpuSuuported())){
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION] = 0; //Internal PLL overvoltage Enable Flag
+ }
+
+ if(!(isBCLKRatioSuuported())){
+ DddtPreFlagHob->PresentFlag[BIOS_PEG_DMI_RATIO_IMPLEMENTATION] = 0; // PEG/DMI ratio Enable Flag
+ }
+
+ DddtPreFlagHob->PresentFlag[BIOS_TDC_VALUE_IMPLEMENTATION] = 0; //TDC Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDP_VALUE_IMPLEMENTATION] = 0; //TDP Flag
+
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(!EFI_ERROR(Status)){
+ OverclockData = &OverclockConfigHob->OverclockData;
+ //Mailbox item
+ //IA core
+ if(!OverclockData->OCCap[IA].VoltageOverridesSupported){
+ DddtPreFlagHob->PresentFlag[BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_IMPLEMENTATION] = 0;
+ }
+ if(!OverclockData->OCCap[IA].VoltageOffsetSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION] = 0;
+ //RING
+ if(!OverclockData->OCCap[RING].RatioOcSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_RING_RATIO_IMPLEMENTATION] = 0;
+ if(!OverclockData->OCCap[RING].VoltageOverridesSupported){
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0;
+ }
+ if(!OverclockData->OCCap[RING].VoltageOffsetSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION] = 0;
+ }
+ }
+
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &WdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = PerfTunePpi->GetSettingData(PeiServices, &SettingData);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(SettingData.RuntimeTurboEanble == 1 && NumOcBins != 0)
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 1;
+ else
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0;
+
+ return Status;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiMiscFuncs
+//
+// Description:
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuPeiMiscFuncs (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+
+#if PERF_TUNE_SUPPORT == 1
+ EFI_STATUS Status;
+
+ Status = CpuPeiIntelXtuDataInit(PeiServices, ReadOnlyVariablePpi, BootMode);
+#endif
+
+ return;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuSmbios.c b/Core/CPU/CpuSmbios.c
new file mode 100644
index 0000000..aa0c42a
--- /dev/null
+++ b/Core/CPU/CpuSmbios.c
@@ -0,0 +1,734 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuSmbios.c 6 6/16/14 4:52a Davidhsieh $
+//
+// $Revision: 6 $
+//
+// $Date: 6/16/14 4:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuSmbios.c $
+//
+// 6 6/16/14 4:52a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Support the cache size which bigger than 0x8000MB
+// [Files] AmiCpuInfo.h, CpuSmbios.c
+//
+// 5 8/14/13 4:53a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Smbios CpuMaxSpeed value is from Cpu when token
+// SMBIOS_TYPE_4_MAX_SPEED is zero
+//
+// 4 2/27/13 5:00a Crystallee
+// [TAG] EIP115822
+// [Category] Improvement
+// [Description] Add SMBIOS type7 information for L4 cache if CPU
+// supported
+// And create a token to control this.
+//
+// 3 3/21/12 4:33a Davidhsieh
+//
+// 2 3/20/12 3:23a Davidhsieh
+// Create SMBIOS type4 and type7 in AMI CPU module part
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSmbios.c
+//
+// Description:
+// Installs TYPE 4 and TYPE 7 SMBIOS tables.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include <Protocol\SmBios.h>
+#include <Protocol\AmiCpuInfo.h>
+#include <Protocol\AmiCpuInfo2.h>
+#include <AmiCspLibInc.h>
+#include <Token.h>
+#include "Cpu.h"
+#include "CpuDxe.h"
+
+extern AMI_CPU_INFO_PROTOCOL gAmiCpuInfoProtocol;
+extern PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+AMI_CPU_INFO *gGetCpuInfo = NULL;
+EFI_SMBIOS_PROTOCOL *gSmbiosProtocol;
+
+UINT32 GetCpuNumByPkgCoreThrd(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+);
+
+UINT32 gType4Instance = 1;
+UINT32 gType7Instance = 1;
+
+EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+
+EFI_EVENT gSmbiosEvent;
+VOID *gSmbiosRegistration = 0;
+
+UINT32 GetBoardSocketNumber(IN UINT32 ApicId);
+UINT8 GetCacheSharedThreads(IN UINT8 Level);
+
+CACHE_DESCRIPTOR_INFO *gCacheDescInfo;
+UINT8 gCacheTypeTable[] = {4, 3, 0, 5};
+UINT8 gAssociativityTable[] = {2, 6 ,4 ,1 ,5 ,1 ,1 ,1 ,7 ,1 ,1 ,1 ,9 ,1 ,1, 1, 8, 1, 1, 1, 0xe,
+ 1, 1, 1, 0xa, 1, 1, 1, 1, 1, 1, 1, 0xb
+};
+
+typedef struct {
+ UINT32 Size;
+ UINT8 Type;
+ UINT8 Assoc;
+} CACHE_INFO;
+
+#if !CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+CACHE_INFO gCacheInfo[3]; //[0] = L1, [1] = L2, [2] = L3
+#else
+CACHE_INFO gCacheInfo[4]; //[0] = L1, [1] = L2, [2] = L3, [3] = L4
+#endif
+
+#define SMBIOS_CACHE_ECC_PARITY 4
+#define SMBIOS_CACHE_ECC_SINGLE_BIT 5
+
+#define SMBIOS_MAX_NUM_SOCKETS 8
+
+CHAR8 *gSocketDesgination[8] = {
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_0),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_1),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_2),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_3),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_4),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_5),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_6),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_7)
+};
+
+
+typedef struct {
+ //Private Data
+ UINT8 *StrBuf;
+ INT32 StrBufSize;
+ INT32 StrBufAvail;
+ UINT8 Tok;
+} SMBIOS_TABLE_STR_BUFFER;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EstablishStringBuffer
+//
+// Description: Initialize string buffer variables
+//
+// Input:
+// IN VOID *Buffer - Buffer address
+// IN UINT32 Size - Buffer Size
+// OUT SMBIOS_TABLE_STR_BUFFER **StrBuffer - String Buffer structure
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EstablishStringBuffer(
+ IN VOID *Buffer,
+ IN UINT32 Size,
+ OUT SMBIOS_TABLE_STR_BUFFER **StrBuffer
+)
+{
+ EFI_STATUS Status;
+ SMBIOS_TABLE_STR_BUFFER *Buf;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBIOS_TABLE_STR_BUFFER), &Buf);
+ ASSERT_EFI_ERROR(Status);
+
+ Buf->StrBuf = Buffer;
+ Buf->StrBufSize = Size;
+ Buf->StrBufAvail = Size;
+ Buf->Tok = 0;
+
+ *StrBuffer = Buf;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AddStrGetTok
+//
+// Description: Add string to buffer and return token value.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+// IN UINT8 *Str - Pointer to string.
+//
+// Output: UINT8 - token of string
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AddStrGetTok(
+ IN SMBIOS_TABLE_STR_BUFFER *StrBuffer,
+ IN UINT8 *Str
+)
+{
+ INT32 Len = (INT32)Strlen(Str);
+
+ if (Len == 0) return 0; //No string
+
+ //For string buffer, 2 bytes at end reserved for double 0, so that is why
+ //gStrBufAvail - 2
+ if (Len > (StrBuffer->StrBufAvail - 2)) return 0; //Not enough space left.
+
+ Strcpy(StrBuffer->StrBuf, Str);
+ StrBuffer->StrBuf += Len + 1;
+ StrBuffer->StrBufAvail -= Len + 1;
+ ++StrBuffer->Tok;
+ return StrBuffer->Tok;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetBufferSizeUsed
+//
+// Description: Get amount storage space used by strings.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+//
+// Output: UINT32 - Size needed for strings.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetBufferSizeUsed(IN SMBIOS_TABLE_STR_BUFFER *StrBuffer)
+{
+ return StrBuffer->StrBufSize - StrBuffer->StrBufAvail;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RemoveStringBuffer
+//
+// Description: Remove String Buffer structure.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID RemoveStringBuffer(IN SMBIOS_TABLE_STR_BUFFER *StrBuffer)
+{
+ pBS->FreePool(StrBuffer);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetMaxSpeedFromBrandString
+//
+// Description: Get the max speed from the brand string.
+//
+// Input:
+// IN CHAR8 *CpuBrandString - Pointer to CPU brand string.
+//
+// Output: UINT32 - frequency found in MHz.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetMaxSpeedFromBrandString(IN CHAR8 *CpuBrandString)
+{
+ UINT32 i;
+ UINT8 CharCount;
+ BOOLEAN TransToMHz = FALSE;
+ BOOLEAN FreqStringFound = FALSE;
+ CHAR8 FrequencyString[] = "0000";
+
+ while (*CpuBrandString != 0) {
+ if (*CpuBrandString == 'G' && *(CpuBrandString + 1) == 'H' && *(CpuBrandString + 2) == 'z') {
+ FreqStringFound = TRUE;
+ TransToMHz = TRUE;
+ break;
+ } else if (*CpuBrandString == 'M' && *(CpuBrandString+1) == 'H' && *(CpuBrandString + 2) == 'z') {
+ FreqStringFound = TRUE;
+ break;
+ } else ++CpuBrandString;
+ }
+
+ --CpuBrandString; //first numeric char
+
+ //search numeric char
+ CharCount = 0;
+ for(i = 0 ; i < 4; ++i) {
+ if (*CpuBrandString >= '0' && *CpuBrandString <= '9') {
+ --CpuBrandString;
+ ++CharCount;
+ } else if (*CpuBrandString == '.') {
+ --CpuBrandString;
+ ++CharCount;
+ } else break;
+ }
+
+ ++CpuBrandString; //first numeric char
+
+ if (FreqStringFound && CharCount > 0) {
+ for(i = 0; i < CharCount; ++i) {
+ if (TransToMHz && *CpuBrandString == '.') CpuBrandString++;
+
+ FrequencyString[i] = *CpuBrandString;
+ ++CpuBrandString;
+ }
+ if (TransToMHz) FrequencyString[3] = '0';
+ } else FreqStringFound = FALSE;
+
+ return FreqStringFound ? Atoi(FrequencyString) : 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CollectCacheInfo
+//
+// Description: Store cache information in variables.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CollectCacheInfo()
+{
+ INT32 i;
+ UINT8 Type;
+ UINT8 Assoc;
+ UINT32 NumCores = NumSupportedCpuCores();
+
+ MemSet(gCacheInfo, sizeof(gCacheInfo), 0);
+
+ gCacheDescInfo = gGetCpuInfo->CacheInfo;
+ for(i = 0; gCacheDescInfo[i].Desc; ++i) { // End of descriptors, Desc = 0.
+ UINT8 Level = gGetCpuInfo->CacheInfo[i].Level;
+ switch(Level) {
+#if !CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ case 1: case 2: case 3:
+#else
+ case 1: case 2: case 3: case 4:
+#endif
+ Type = gCacheTypeTable[gCacheDescInfo[i].Type];
+
+ if (gCacheDescInfo[i].Associativity < sizeof(gAssociativityTable)/sizeof(UINT8))
+ Assoc = gAssociativityTable[gCacheDescInfo[i].Associativity];
+ else Assoc = 1;
+
+ //If multiple caches of same level, add sizes.
+ gCacheInfo[Level - 1].Size += gCacheDescInfo[i].Size;
+
+ //If multiple caches of same level have different types report as other.
+ if (gCacheInfo[Level - 1].Type == 0) gCacheInfo[Level - 1].Type = Type;
+ else if (gCacheInfo[Level - 1].Type != Type) gCacheInfo[Level - 1].Type = 1;
+
+ if (gCacheInfo[Level - 1].Assoc == 0) gCacheInfo[Level - 1].Assoc = Assoc;
+ else if (gCacheInfo[Level - 1].Assoc != Assoc) gCacheInfo[Level - 1].Assoc = 1;
+ }
+ }
+
+ if (GetCacheSharedThreads(1) <= 2) gCacheInfo[0].Size *= NumCores;
+ if (GetCacheSharedThreads(2) <= 2) gCacheInfo[1].Size *= NumCores;
+ if (GetCacheSharedThreads(3) <= 2) gCacheInfo[2].Size *= NumCores;
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ if (GetCacheSharedThreads(4) <= 2) gCacheInfo[3].Size *= NumCores;
+#endif
+}
+
+#define TYPE7_STRING_BUFFER_SIZE 100
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateSmbiosTable7
+//
+// Description: Create SMBIOS Table 7
+//
+// Input: IN UINT8 CacheLevel (L1, L2, L3)
+//
+// Output: UINT16 - Handle for table.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CreateSmbiosTable7(IN UINT8 CacheLevel)
+{
+ SMBIOS_CACHE_INFO *CacheInfo;
+ UINT16 Handle;
+ EFI_STATUS Status;
+ UINT32 Type7ActStrBufSize;
+ SMBIOS_TABLE_STR_BUFFER *StrBuffer;
+
+ if (gCacheInfo[CacheLevel-1].Size == 0) return 0xffff;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBIOS_CACHE_INFO) + TYPE7_STRING_BUFFER_SIZE, &CacheInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ EstablishStringBuffer((UINT8*)CacheInfo + sizeof(SMBIOS_CACHE_INFO), TYPE7_STRING_BUFFER_SIZE, &StrBuffer);
+
+ Handle = gSmbiosProtocol->SmbiosGetFreeHandle();
+
+ CacheInfo->StructureType.Type = 7;
+ CacheInfo->StructureType.Length = 0x13;
+ CacheInfo->StructureType.Handle = Handle;
+ CacheInfo->SocketDesignation = 0;
+
+ if(gCacheInfo[CacheLevel-1].Size > 0x07FFF){
+ CacheInfo->MaxCacheSize = 0x8000 | (gCacheInfo[CacheLevel-1].Size / 64);
+ CacheInfo->InstalledSize = 0x8000 | (gCacheInfo[CacheLevel-1].Size / 64);
+ } else {
+ CacheInfo->MaxCacheSize = gCacheInfo[CacheLevel-1].Size;
+ CacheInfo->InstalledSize = gCacheInfo[CacheLevel-1].Size;
+ }
+
+ CacheInfo->SystemCacheType = gCacheInfo[CacheLevel-1].Type;
+ CacheInfo->Associativity = gCacheInfo[CacheLevel-1].Assoc;
+
+ switch (CacheLevel) {
+ case 1:
+ CacheInfo->CacheConfig = 0x180;
+#ifdef SMBIOS_TYPE_7_L1_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L1_SOCKET_DESIGNATION));
+#endif
+ break;
+ case 2:
+ CacheInfo->CacheConfig = 0x181;
+#ifdef SMBIOS_TYPE_7_L2_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L2_SOCKET_DESIGNATION));
+#endif
+ break;
+ case 3:
+ CacheInfo->CacheConfig = 0x182;
+#ifdef SMBIOS_TYPE_7_L3_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L3_SOCKET_DESIGNATION));
+#endif
+ break;
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ case 4:
+ CacheInfo->CacheConfig = 0x183;
+#ifdef SMBIOS_TYPE_7_L4_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L4_SOCKET_DESIGNATION));
+#endif
+ break;
+#endif
+ }
+
+ CacheInfo->SupportSRAM = 2;
+ CacheInfo->CurrentSRAM = 2;
+ CacheInfo->CacheSpeed = 0;
+ CacheInfo->ErrorCorrectionType = 0x05; //ECC
+ Type7ActStrBufSize = GetBufferSizeUsed(StrBuffer);
+
+ if (Type7ActStrBufSize == 0) {
+ *(UINT16*)(CacheInfo + 1) = 0; //Double NULL.
+ } else {
+ *((UINT8*)(CacheInfo + 1) + Type7ActStrBufSize) = 0; //End structure of NULL.
+ }
+
+ Status = gSmbiosProtocol->SmbiosAddStrucByHandle(
+ Handle,
+ (VOID*)CacheInfo,
+ (UINT16)(sizeof(SMBIOS_CACHE_INFO) + (Type7ActStrBufSize == 0 ? 2 : Type7ActStrBufSize + 1))
+ );
+
+ pBS->FreePool(CacheInfo);
+ RemoveStringBuffer(StrBuffer);
+
+ return !EFI_ERROR(Status) ? Handle : 0xffff;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AutodetectFamily
+//
+// Description: Return family type from Brand String.
+//
+// Input: IN CHAR8 *BrandString
+//
+// Output: UINT8 - Family
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AutodetectFamily(IN CHAR8 *BrandString)
+{
+ CHAR8 *p = BrandString;
+
+ while(*p) {
+ if (MemCmp(p, "Xeon", 4) == 0) return 0xb3;
+ if (MemCmp(p, "i7", 2) == 0) return 0xc6;
+ if (MemCmp(p, "i5", 2) == 0) return 0xcd;
+ if (MemCmp(p, "i3", 2) == 0) return 0xce;
+ if (MemCmp(p, "Pentiu", 6) == 0) return 0x0b;
+ if (MemCmp(p, "Celero", 6) == 0) return 0x0f;
+ ++p;
+ }
+
+ return 0xcd; //default as i5 family
+}
+
+#define TYPE4_STRING_BUFFER_SIZE 200
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateSmbiosTable4
+//
+// Description: Create SMBIOS Table 4
+//
+// Input: IN UINT32 PhysSocket
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateSmbiosTable4(IN UINT32 PhysSocket)
+{
+ SMBIOS_PROCESSOR_INFO * ProcInfo;
+ EFI_STATUS Status;
+ UINT32 ActStrBufSize;
+ UINT32 MaxFreqBrandStr;
+ SMBIOS_TABLE_STR_BUFFER *StrBuffer;
+ SMBIOS_STRUCTURE_HEADER *Hdr;
+ UINT16 Size;
+ BOOLEAN HandleExists = FALSE;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData, sizeof(SMBIOS_PROCESSOR_INFO) + TYPE4_STRING_BUFFER_SIZE, &ProcInfo
+ );
+
+ EstablishStringBuffer((UINT8*)ProcInfo + sizeof(SMBIOS_PROCESSOR_INFO), TYPE4_STRING_BUFFER_SIZE, &StrBuffer);
+
+ ProcInfo->StructureType.Type = 4;
+ ProcInfo->StructureType.Length = 0x2a;
+ ProcInfo->StructureType.Handle = 0xffff; //To be updated by SMBIOS driver.
+
+ if (PhysSocket >= SMBIOS_MAX_NUM_SOCKETS) ProcInfo->SocketDesignation = 0;
+ else ProcInfo->SocketDesignation = AddStrGetTok(StrBuffer, gSocketDesgination[PhysSocket]);
+
+ ProcInfo->ProcessotType = 3; //Central processor
+
+ if (SMBIOS_TYPE_4_PROC_FAMILY != 0) ProcInfo->Family = SMBIOS_TYPE_4_PROC_FAMILY;
+ else ProcInfo->Family = AutodetectFamily(gGetCpuInfo->BrandString);
+
+ ProcInfo->ProcessorManufacturer = AddStrGetTok(StrBuffer, "Intel");
+
+ ProcInfo->ProcessorID_1 = (UINT32)(gGetCpuInfo->Version);
+ ProcInfo->ProcessorID_2 = (UINT32)(gGetCpuInfo->Features);
+ ProcInfo->ProcessorVersion = AddStrGetTok(StrBuffer, gGetCpuInfo->BrandString);
+ ProcInfo->Voltage = (UINT8)(12) + BIT7; // 1.2 volts
+ //ProcInfo->Voltage = BIT7; // 1.2 volts
+ ProcInfo->MaxSpeed = SMBIOS_TYPE_4_MAX_SPEED;
+
+ MaxFreqBrandStr = GetMaxSpeedFromBrandString(gGetCpuInfo->BrandString);
+ if (MaxFreqBrandStr) ProcInfo->CurrentSpeed = MaxFreqBrandStr;
+ else ProcInfo->CurrentSpeed = gGetCpuInfo->IntendedFreq;
+
+#if !SMBIOS_TYPE_4_MAX_SPEED
+ ProcInfo->MaxSpeed = ProcInfo->CurrentSpeed;
+#endif
+ ProcInfo->ExtClockFreq = (UINT16)(gGetCpuInfo->FSBFreq);
+ ProcInfo->Status = 0x41; //Populated and enabled.
+ ProcInfo->Upgrade = SMBIOS_TYPE_4_PROC_UPGRADE;
+ ProcInfo->SerialNumber = 0;
+
+#ifdef SMBIOS_TYPE_4_ASSET_TAG
+ ProcInfo->AssetTag = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_4_ASSET_TAG));
+#else
+ ProcInfo->AssetTag = 0;
+#endif
+#ifdef SMBIOS_TYPE_4_PART_NUMBER
+ ProcInfo->PartNumber = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_4_PART_NUMBER));
+#else
+ ProcInfo->PartNumber = 0;
+#endif
+ ProcInfo->CoreCount = NumSupportedCpuCores(); //This must be the same across sockets.
+ ProcInfo->CoreEnabled = gGetCpuInfo->NumCores;
+ ProcInfo->ThreadCount = NumSupportedCpuCores() * NumSupportedThreadsPerCore(); //This must be the same across sockets.
+ ProcInfo->ProcessorChar = 4; //X64 Support
+ ProcInfo->Family2 = ProcInfo->Family;
+
+ ActStrBufSize = GetBufferSizeUsed(StrBuffer);
+ if (ActStrBufSize == 0) {
+ *(UINT16*)(ProcInfo + 1) = 0; //Double NULL.
+ } else {
+ *((UINT8*)(ProcInfo + 1) + ActStrBufSize) = 0; //End structure of NULL.
+ }
+
+ Status = gSmbiosProtocol->SmbiosAddStructure(
+ (VOID*)ProcInfo,
+ (UINT16)(sizeof(SMBIOS_PROCESSOR_INFO) + (ActStrBufSize == 0 ? 2 : ActStrBufSize + 1))
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gSmbiosProtocol->SmbiosReadStrucByType(4, 1, (UINT8**)&Hdr, &Size);
+ ProcInfo->StructureType.Handle = Hdr->Handle;
+ ProcInfo->L1CacheHandle = CreateSmbiosTable7(1);
+ ProcInfo->L2CacheHandle = CreateSmbiosTable7(2);
+ ProcInfo->L3CacheHandle = CreateSmbiosTable7(3);
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ CreateSmbiosTable7(4);
+#endif
+ Status = gSmbiosProtocol->SmbiosWriteStructure(
+ ProcInfo->StructureType.Handle,
+ (VOID*)ProcInfo,
+ (UINT16)(sizeof(SMBIOS_PROCESSOR_INFO) + (ActStrBufSize == 0 ? 2 : ActStrBufSize + 1))
+ );
+
+ pBS->FreePool(ProcInfo);
+ RemoveStringBuffer(StrBuffer);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateCpuSmbiosTables
+//
+// Description: Create CPU SMBIOS Tables 4 and 7.
+//
+// Input:
+// IN EFI_EVENT Event - Not used
+// IN VOID *Context - Note Used
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateCpuSmbiosTables(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT32 NumSocketsPop = NumberOfCpuSocketsPopulated();
+ UINT32 SocketPopBitmap = 0;
+ SMBIOS_STRUCTURE_HEADER *Hdr;
+ UINT16 Size;
+ UINT32 Cpu;
+
+ ASSERT(NUMBER_CPU_SOCKETS <= SMBIOS_MAX_NUM_SOCKETS);
+
+ Status = pBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, &gSmbiosProtocol);
+ if (EFI_ERROR(Status)) return; //First call, error, because protocol not installed yet.
+
+//Delete existing CPU SBIOS structures type 4 and type 7.
+ while (!EFI_ERROR(gSmbiosProtocol->SmbiosReadStrucByType(4, 1, (UINT8**)&Hdr, &Size))) {
+ gSmbiosProtocol->SmbiosDeleteStructure(Hdr->Handle);
+ pBS->FreePool(Hdr);
+ }
+
+ while (!EFI_ERROR(gSmbiosProtocol->SmbiosReadStrucByType(7, 1, (UINT8**)&Hdr, &Size))) {
+ gSmbiosProtocol->SmbiosDeleteStructure(Hdr->Handle);
+ pBS->FreePool(Hdr);
+ }
+
+//Add CPU SMBIOS structures for populated sockets.
+ Cpu = 0;
+ for (i = 0; i < NumSocketsPop; ++i) {
+ UINT32 ApicId;
+ UINT32 PhysSocket;
+
+ Status = gAmiCpuInfoProtocol.GetCpuInfo(&gAmiCpuInfoProtocol, Cpu, &gGetCpuInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ CollectCacheInfo(); //For one thread.
+
+ Status = ((AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2)->GetApicInfo(
+ (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2, i, 0, 0, &ApicId, NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) ApicId = 0;
+ PhysSocket = GetBoardSocketNumber(ApicId);
+
+ CreateSmbiosTable4(PhysSocket);
+ if (PhysSocket < SMBIOS_MAX_NUM_SOCKETS) SocketPopBitmap |= 1 << PhysSocket;
+
+ //Update Cpu from gGetCpuInfo
+ Cpu += gGetCpuInfo->NumCores * (gGetCpuInfo->NumHts == 0 ? 1 : 2);
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CpuSmbios
+//
+// Description: Create CPU SMBIOS Tables. Installs notification on SMBIOS handlers.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuSmbios()
+{
+ EFI_STATUS Status;
+
+ Status = RegisterProtocolCallback(
+ &gEfiSmbiosProtocolGuid,
+ CreateCpuSmbiosTables,
+ NULL,
+ &gSmbiosEvent,
+ &gSmbiosRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ CreateCpuSmbiosTables(gSmbiosEvent, NULL);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuSpSmi.DXS b/Core/CPU/CpuSpSmi.DXS
new file mode 100644
index 0000000..9362072
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.DXS
@@ -0,0 +1,59 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.DXS 1 2/07/12 4:00a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 4:00a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.DXS $
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSpSmi.DXS
+//
+// Description: Dependency file for the CpuSp SMI
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CpuSpSmi.h"
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CPU/CpuSpSmi.c b/Core/CPU/CpuSpSmi.c
new file mode 100644
index 0000000..bd4469d
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.c
@@ -0,0 +1,568 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c 8 5/24/15 11:37p Davidhsieh $
+//
+// $Revision: 8 $
+//
+// $Date: 5/24/15 11:37p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c $
+//
+// 8 5/24/15 11:37p Davidhsieh
+// [TAG] EIP215675
+// [Category] New Feature
+// [Description] Smm Access Check feautre support
+// [Files] Cpu.sdl, CpuDxe.c, CpuSpSmi.sdl, CpuSpsmi.c
+//
+// 7 10/08/13 3:10a Crystallee
+// [TAG] EIP137873
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CPU Security Configuration(MSR 4E0[0]) will be changed
+// after S3 resume
+// [RootCause] Didn't restore the Cpu MSR 4e0 while S3 resume.
+// [Solution] Restore the Cpu MSR 0x4E0 while S3 resume.
+//
+// 6 1/24/13 10:45p Davidhsieh
+// [TAG] EIP112381
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TBoot S3 resume fail
+// [RootCause] MSR 0x2e7 is not restored
+// [Solution] Save and restore MSR 0x2e7 for S3
+//
+// 5 12/18/12 9:23p Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Check CPU before lock SMM_FEATURE_CONTROL MSR
+//
+// 4 12/09/12 10:35p Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Lock SMM_FEATURE_CONTROL MSR
+//
+// 3 10/04/12 9:20a Davidhsieh
+// Change the procedure of configuring MTRR
+//
+// 2 7/10/12 2:51a Davidhsieh
+// [TAG] EIP93180
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The "Event Kernel-Power 137" error event log shows while
+// resumed from S3
+// [RootCause] The fixed and variable Mtrrs of BSP are not restored
+// [Solution] Restore BPS's mtrss
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSpSmi.C
+//
+// Description: Provide functions to CPU specific SMI
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CpuSpSmi.h"
+
+UINT64 ReadMsr (UINT32 Msr);
+VOID WriteMsr(UINT32 Msr, UINT64 Value);
+
+UINTN MpMtrrSynchUpEntry (VOID);
+VOID MpMtrrSynchUpExit (UINTN Cr4);
+
+EFI_GUID SwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_SMM_BASE_PROTOCOL *pSmmBase;
+EFI_SMM_SW_DISPATCH_PROTOCOL *gSwDispatch;
+
+//
+// MSR table for S3 resume
+//
+EFI_MSR_VALUES mFixedMtrrValues[] = {
+ { MTRR_FIX_64K_00000, 0 },
+ { MTRR_FIX_16K_80000, 0 },
+ { MTRR_FIX_16K_A0000, 0 },
+ { MTRR_FIX_4K_C0000, 0 },
+ { MTRR_FIX_4K_C8000, 0 },
+ { MTRR_FIX_4K_D0000, 0 },
+ { MTRR_FIX_4K_D8000, 0 },
+ { MTRR_FIX_4K_E0000, 0 },
+ { MTRR_FIX_4K_E8000, 0 },
+ { MTRR_FIX_4K_F0000, 0 },
+ { MTRR_FIX_4K_F8000, 0 },
+ { 0, 0 }
+};
+
+EFI_MSR_VALUES mVariableMtrrValues[] = {
+ { MTRR_PHYS_BASE_0, 0 },
+ { MTRR_PHYS_MASK_0, 0 },
+ { MTRR_PHYS_BASE_1, 0 },
+ { MTRR_PHYS_MASK_1, 0 },
+ { MTRR_PHYS_BASE_2, 0 },
+ { MTRR_PHYS_MASK_2, 0 },
+ { MTRR_PHYS_BASE_3, 0 },
+ { MTRR_PHYS_MASK_3, 0 },
+ { MTRR_PHYS_BASE_4, 0 },
+ { MTRR_PHYS_MASK_4, 0 },
+ { MTRR_PHYS_BASE_5, 0 },
+ { MTRR_PHYS_MASK_5, 0 },
+ { MTRR_PHYS_BASE_6, 0 },
+ { MTRR_PHYS_MASK_6, 0 },
+ { MTRR_PHYS_BASE_7, 0 },
+ { MTRR_PHYS_MASK_7, 0 },
+ { MTRR_PHYS_BASE_8, 0 },
+ { MTRR_PHYS_MASK_8, 0 },
+ { MTRR_PHYS_BASE_9, 0 },
+ { MTRR_PHYS_MASK_9, 0 }
+};
+
+#define MiscMsrCount 1
+
+EFI_MSR_VALUES mMiscMsrValues[] = {
+ { 0x2e7, 0 }
+};
+
+EFI_MSR_VALUES mSmmFeatureCtrl = { 0x4e0, 0};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveCpuMsr
+//
+// Description: This function saves the CPU MSRs for S3 resume usage.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SaveCpuMsr(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UINT32 i;
+
+ if (Shr64(ReadMsr(0x17d),57) & 0x03){
+ if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01))
+ WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01);
+ mSmmFeatureCtrl.Value = ReadMsr(mSmmFeatureCtrl.Index);
+ }
+
+ //Save Fixed MTRR
+ for(i=0; i < NUM_OF_FIXED_MTRRS; i++)
+ {
+ mFixedMtrrValues[i].Value = ReadMsr(mFixedMtrrValues[i].Index);
+ }
+
+ //Save variable MTRR
+ for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++)
+ {
+ mVariableMtrrValues[i * 2].Value = ReadMsr(mVariableMtrrValues[i * 2].Index);
+ mVariableMtrrValues[i * 2 + 1].Value = ReadMsr(mVariableMtrrValues[i * 2 + 1].Index);
+ }
+
+ mMiscMsrValues[0].Value = ReadMsr(mMiscMsrValues[0].Index);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreMsrOnCpu
+//
+// Description: This function restores the CPU MSRs during S3 resume.
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreMsrOnCpu(IN VOID *data)
+{
+ UINT32 i;
+ UINTN Cr4;
+
+ Cr4 = MpMtrrSynchUpEntry();
+
+ //Restore Fixed MTRR
+ for(i=0; i < NUM_OF_FIXED_MTRRS; i++)
+ {
+ WriteMsr(mFixedMtrrValues[i].Index, mFixedMtrrValues[i].Value );
+ }
+
+ //Restore variable MTRR
+ for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++)
+ {
+ WriteMsr(mVariableMtrrValues[i * 2].Index, mVariableMtrrValues[i * 2].Value );
+ WriteMsr(mVariableMtrrValues[i * 2 + 1].Index, mVariableMtrrValues[i * 2 + 1].Value );
+ }
+
+ MpMtrrSynchUpExit (Cr4);
+
+ WriteMsr(mMiscMsrValues[0].Index, mMiscMsrValues[0].Value);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreCpuMsr
+//
+// Description: This function restores the CPU MSRs during S3 resume.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreCpuMsr(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UINT32 i;
+ UINTN Cr4;
+
+ if (Shr64(ReadMsr(0x17d),57) & 0x03){
+ if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01)){
+ WriteMsr(mSmmFeatureCtrl.Index, (mSmmFeatureCtrl.Value & ~0x01));
+ WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01);
+ }
+ }
+
+ for (i = 0; i < pSmst->NumberOfCpus; ++i) {
+ pSmst->SmmStartupThisAp(RestoreMsrOnCpu, i, NULL);
+ }
+
+ Cr4 = MpMtrrSynchUpEntry();
+ RestoreMsrOnCpu(NULL);
+ MpMtrrSynchUpExit (Cr4);
+}
+
+#define SMRAM_CPU_DATA_VARIABLE_GUID \
+ { \
+ 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
+ }
+
+#define SMRAM_CPU_DATA_VARIABLE L"SmramCpuDataVar"
+
+#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
+
+EFI_GUID mSmramCpuDataVariableGuid = SMRAM_CPU_DATA_VARIABLE_GUID;
+BOOLEAN mLocked = FALSE;
+
+/**
+ Dispatch function for a Software SMI handler.
+
+ @param DispatchHandle The handle of this dispatch function.
+ @param DispatchContext The pointer to the dispatch function's context.
+ The SwSmiInputValue field is filled in
+ by the software dispatch driver prior to
+ invoking this dispatch function.
+ The dispatch function will only be called
+ for input values for which it is registered.
+
+ @return None
+
+**/
+VOID
+EFIAPI
+SmramSaveInfoHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+/**
+
+@brief
+
+ Dispatch function for a Software SMI handler
+
+ @param[in] DispatchHandle - The handle of this dispatch function.
+ @param[in] DispatchContext - The pointer to the dispatch function's context.
+
+
+**/
+{
+ EFI_STATUS Status;
+ UINT64 VarData[3];
+ UINTN VarSize;
+
+ if (!mLocked && IoRead8 (SW_SMI_IO_ADDRESS+1) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
+ VarSize = sizeof (VarData);
+ Status = pRS->GetVariable (
+ SMRAM_CPU_DATA_VARIABLE,
+ &mSmramCpuDataVariableGuid,
+ NULL,
+ &VarSize,
+ VarData
+ );
+ if (!EFI_ERROR (Status) && VarSize == sizeof (VarData)) {
+ MemCpy (
+ (VOID *) (UINTN) (VarData[0]),
+ (VOID *) (UINTN) (VarData[1]),
+ (UINTN) (VarData[2])
+ );
+ }
+
+ mLocked = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSmmFeatureEn
+//
+// Description:
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CpuSmmFeatureEn(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+
+ UINT64 MsrData;
+
+ if (Shr64(ReadMsr(0x17d),58) & 0x01){
+ if (!(ReadMsr(0x4e0) && 0x01)){
+ MsrData = ReadMsr(0x4e0);
+ MsrData |= 0x4;
+ WriteMsr(0x4e0, MsrData);
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: Called from InstallSmiHandler
+//
+// Input:
+//
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ EFI_SMM_SW_DISPATCH_CONTEXT Save_CPU_MSR = {SW_SMI_SAVE_MSR};
+ EFI_SMM_SW_DISPATCH_CONTEXT Restore_CPU_MSR = {SW_SMI_RESTORE_MSR};
+ EFI_SMM_SW_DISPATCH_CONTEXT CpuDriverSaveInfo = { SMM_FROM_SMBASE_DRIVER };
+ EFI_SMM_SW_DISPATCH_CONTEXT CpuSmmFeatureEnable = {SW_SMI_ENABLE_SMM_FEATURE};
+
+ Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ SaveCpuMsr,
+ &Save_CPU_MSR,
+ &Handle
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ RestoreCpuMsr,
+ &Restore_CPU_MSR,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ SmramSaveInfoHandler,
+ &CpuDriverSaveInfo,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ CpuSmmFeatureEn,
+ &CpuSmmFeatureEnable,
+ &Handle
+ );
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ /*Status = pBS->LocateProtocol (&gEfiSmmThunkProtocolGuid, NULL, &mSmmThunk);
+ if (EFI_ERROR(Status)) {
+ TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol not located.\n"));
+ } else {
+ TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol located.\n"));
+ }*/
+
+ pSmmBase->GetSmstLocation (pSmmBase, &mSmst);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NotInSmmFunction
+//
+// Description: If Not In Smm Function
+//
+// Input:
+//
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(
+ )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSpSmiInit
+//
+// Description: Initializes CPU specific SMM Drivers.
+//
+// Input:
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Here is the control flow of this function:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuSpSmiInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch);
+ //if (EFI_ERROR(Status)) return Status;
+//InitSmmHandler
+
+ // return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NonSmmElinkFunctions);
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/CPU/CpuSpSmi.cif b/Core/CPU/CpuSpSmi.cif
new file mode 100644
index 0000000..9f0e181
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "CpuSp SMI"
+ category = ModulePart
+ LocalRoot = "Core\CPU
+ RefName = "CpuSpSMI"
+[files]
+"CpuSpSmi.sdl"
+"CpuSpSmi.mak"
+"CpuSpSmi.h"
+"CpuSpSmi.c"
+"CpuSpSmi.DXS"
+<endComponent>
diff --git a/Core/CPU/CpuSpSmi.h b/Core/CPU/CpuSpSmi.h
new file mode 100644
index 0000000..bb05202
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.h
@@ -0,0 +1,118 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.h 1 2/07/12 4:00a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 4:00a $
+//
+//*********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.h $
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//*********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <CpuSpSmi.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the CpuSpSMI Component
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CPUSPSMI_H_
+#define _CPUSPSMI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <AmiDxeLib.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <Token.h>
+
+#define NUM_OF_FIXED_MTRRS 11
+
+#define MSR_IA32_MTRR_CAP 0xFE
+ #define VCNT_MASK 0xFF
+
+#define MTRR_PHYS_BASE_0 0x200
+#define MTRR_PHYS_MASK_0 0x201
+#define MTRR_PHYS_BASE_1 0x202
+#define MTRR_PHYS_MASK_1 0x203
+#define MTRR_PHYS_BASE_2 0x204
+#define MTRR_PHYS_MASK_2 0x205
+#define MTRR_PHYS_BASE_3 0x206
+#define MTRR_PHYS_MASK_3 0x207
+#define MTRR_PHYS_BASE_4 0x208
+#define MTRR_PHYS_MASK_4 0x209
+#define MTRR_PHYS_BASE_5 0x20a
+#define MTRR_PHYS_MASK_5 0x20b
+#define MTRR_PHYS_BASE_6 0x20c
+#define MTRR_PHYS_MASK_6 0x20d
+#define MTRR_PHYS_BASE_7 0x20e
+#define MTRR_PHYS_MASK_7 0x20f
+#define MTRR_PHYS_BASE_8 0x210
+#define MTRR_PHYS_MASK_8 0x211
+#define MTRR_PHYS_BASE_9 0x212
+#define MTRR_PHYS_MASK_9 0x213
+#define MTRR_FIX_64K_00000 0x250
+#define MTRR_FIX_16K_80000 0x258
+#define MTRR_FIX_16K_A0000 0x259
+#define MTRR_FIX_4K_C0000 0x268
+#define MTRR_FIX_4K_C8000 0x269
+#define MTRR_FIX_4K_D0000 0x26a
+#define MTRR_FIX_4K_D8000 0x26b
+#define MTRR_FIX_4K_E0000 0x26c
+#define MTRR_FIX_4K_E8000 0x26d
+#define MTRR_FIX_4K_F0000 0x26e
+#define MTRR_FIX_4K_F8000 0x26f
+
+typedef struct _EFI_MSR_VALUES {
+ UINT16 Index;
+ UINT64 Value;
+} EFI_MSR_VALUES;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _IDESMM_H_
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CPU/CpuSpSmi.mak b/Core/CPU/CpuSpSmi.mak
new file mode 100644
index 0000000..e25e332
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.mak
@@ -0,0 +1,65 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.mak 1 2/07/12 4:00a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 2/07/12 4:00a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.mak $
+#
+# 1 2/07/12 4:00a Davidhsieh
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CpuSpSmi.mak
+#
+# Description: Make file for the CpuSpSMI component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CPUSPSMI
+
+CPUSPSMI : $(BUILD_DIR)\CpuSpSmi.mak CpuSpSmiBin
+
+$(BUILD_DIR)\CpuSpSmi.mak : $(CPUSPSMI_DIR)\$(@B).cif $(CPUSPSMI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CPUSPSMI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CpuSpSmiBin : $(AMIDXELIB)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CpuSpSmi.mak all\
+ GUID=116e1acf-2533-4cc2-820a-bbc10a2aB07c\
+ ENTRY_POINT=CpuSpSmiInit\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/CpuSpSmi.sdl b/Core/CPU/CpuSpSmi.sdl
new file mode 100644
index 0000000..be2e366
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.sdl
@@ -0,0 +1,56 @@
+TOKEN
+ Name = "CPUSPSMI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IDESMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_SAVE_MSR"
+ Value = "0x56"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_RESTORE_MSR"
+ Value = "0x57"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_ENABLE_SMM_FEATURE"
+ Value = "0x58"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_S3_RESTORE_MSR_FROM_SDL"
+ Value = "0x59"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "CPUSPSMI_DIR"
+End
+
+MODULE
+ Help = "Includes CpuSpSmi.mak to Project"
+ File = "CpuSpSmi.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CpuSpSmi.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/CPU/CpuTools.cif b/Core/CPU/CpuTools.cif
new file mode 100644
index 0000000..1cafb1b
--- /dev/null
+++ b/Core/CPU/CpuTools.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "CpuTools"
+ category = ModulePart
+ LocalRoot = "Core\Cpu"
+ RefName = "CpuTools"
+[files]
+"CpuTools.sdl"
+"SecFixup.exe"
+"CreateSecFfs.exe"
+<endComponent>
diff --git a/Core/CPU/CpuTools.sdl b/Core/CPU/CpuTools.sdl
new file mode 100644
index 0000000..b259ecf
--- /dev/null
+++ b/Core/CPU/CpuTools.sdl
@@ -0,0 +1,13 @@
+TOKEN
+ Name = CpuTools_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable CpuTools support in Project"
+End
+
+PATH
+ Name = "CPU_TOOLS_DIR"
+End
diff --git a/Core/CPU/CreateSecFfs.exe b/Core/CPU/CreateSecFfs.exe
new file mode 100644
index 0000000..345c2e5
--- /dev/null
+++ b/Core/CPU/CreateSecFfs.exe
Binary files differ
diff --git a/Core/CPU/IA32/AmiIa32Lib.cif b/Core/CPU/IA32/AmiIa32Lib.cif
new file mode 100644
index 0000000..e86bed7
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AmiIa32Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "AmiIa32Lib"
+[files]
+"AmiIa32Lib.sdl"
+"AmiIa32Lib.mak"
+"IA32CLib.c"
+"IA32AsmLib\EnableLongMode.asm"
+"IA32AsmLib\EnableMachineCheck.asm"
+<endComponent>
diff --git a/Core/CPU/IA32/AmiIa32Lib.mak b/Core/CPU/IA32/AmiIa32Lib.mak
new file mode 100644
index 0000000..304209c
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.mak
@@ -0,0 +1,67 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak 1 10/13/06 8:36p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 10/13/06 8:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak $
+#
+# 1 10/13/06 8:36p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiIa32Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+AmiIa32Lib : $(BUILD_DIR)\AmiIa32Lib.mak AmiIa32LibBin
+
+$(BUILD_DIR)\AmiIa32Lib.mak : $(AmiIa32Lib_DIR)\$(@B).cif $(AmiIa32Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiIa32Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+AmiDxeLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ELSEIF "$(PROCESSOR)"=="x64"
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ENDIF
+
+AmiIa32LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiIa32Lib.mak all\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/AmiIa32Lib.sdl b/Core/CPU/IA32/AmiIa32Lib.sdl
new file mode 100644
index 0000000..8581f00
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "AmiIa32Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiIa32Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AmiIa32Lib_DIR"
+End
+
+MODULE
+ Help = "Includes AmiIa32Lib.mak to Project"
+ File = "AmiIa32Lib.mak"
+End
+
diff --git a/Core/CPU/IA32/FoundationIa32.cif b/Core/CPU/IA32/FoundationIa32.cif
new file mode 100644
index 0000000..8f9a179
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "FoundationIa32"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "FoundationIa32"
+[files]
+"FoundationIa32.sdl"
+"FoundationIa32.mak"
+"efijump.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"Processor.c"
+"ProcessorAsms.Asm"
+"SwitchCoreStacks.asm"
+"Processor.h"
+<endComponent>
diff --git a/Core/CPU/IA32/FoundationIa32.mak b/Core/CPU/IA32/FoundationIa32.mak
new file mode 100644
index 0000000..93f45d4
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.mak
@@ -0,0 +1,69 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak 1 8/24/06 12:35p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:35p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak $
+#
+# 1 8/24/06 12:35p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FoundationIa32.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+FoundationIa32 : $(BUILD_DIR)\FoundationIa32.mak FoundationIa32Bin
+
+$(BUILD_DIR)\FoundationIa32.mak : $(FoundationIa32_DIR)\$(@B).cif $(FoundationIa32_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FoundationIa32_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+FoundationBin : $(BUILD_DIR)\FoundationIa32.lib
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ELSEIF "$(PROCESSOR)"=="x64"
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ENDIF
+
+
+FoundationIa32Bin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FoundationIa32.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/FoundationIa32.sdl b/Core/CPU/IA32/FoundationIa32.sdl
new file mode 100644
index 0000000..67f7c70
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "FoundationIa32_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FoundationIa32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FoundationIa32_DIR"
+End
+
+MODULE
+ Help = "Includes FoundationIa32.mak to Project"
+ File = "FoundationIa32.mak"
+End
+
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
new file mode 100644
index 0000000..14af3dd
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
@@ -0,0 +1,143 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableLongMode.asm 2 8/06/12 2:43p Markw $
+;
+; $Revision: 2 $
+;
+; $Date: 8/06/12 2:43p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableLongMode
+;
+; Description:
+; VOID EnableLongMode(IN VOID *PageTable, IN VOID *Function,
+; IN VOID *Parameter1, IN VOID *Parameter2) enables long mode then calls the
+; provided function with the provided parameters.
+;
+; Input:
+; IN VOID *PageTable
+; Pointer to level 4 page map.
+;
+; IN VOID *Function
+; Pointer to function to call.
+;
+; IN VOID *Parameter1
+; Parameter 1 for above function call.
+;
+; IN VOID *Parameter2
+; Parameter 2 for above function call.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableLongMode proc C public PageTable:DWORD, Function:DWORD, Parameter1:DWORD, Parameter2:DWORD
+ mov eax, PageTable
+ mov cr3, eax ;Set CR3 to first page directory pointer table
+
+ mov eax, cr4
+ or ax, 620h ;Enable PAE and XMM in case it was turned off.
+ mov cr4, eax
+
+ ;Enable long mode in msr register. Doesn't actually enter long mode yet.
+ mov ecx, 0c0000080h
+ rdmsr
+ bts eax, 8
+ wrmsr
+
+ ;Enable paging
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax ;Now in long mode compatiblity.
+ jmp @f
+@@:
+
+ ;jmp far segment:offset
+ db 67h, 0eah
+ dd offset long_mode_64
+ dw 38h ;SYS_CODE64_SEL
+long_mode_64:
+ ;in 64-bit long mode
+
+ db 48h
+ xor eax, eax ;xor rax, rax
+ db 48h
+ xor ebx, ebx ;xor rbx, rbx
+ db 48h
+ xor ecx, ecx ;xor rcx, rcx
+ db 48h
+ xor edx, edx ;xor rdx, rdx
+
+ mov ecx, Parameter1
+ mov edx, Parameter2
+ mov ebx, Function
+
+ mov ax, 30h ;SYS_DATA64_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ push 37fh
+ fldcw word ptr [esp] ;Uses rsp. Set FP control word according UEFI
+ db 48h
+ add esp, 8 ;add rsp, 8
+
+
+ mov eax, 0fffffff0h
+ db 48h
+ and esp, eax ;rsp must be on a 16 byte boundary. C compiler expects that.
+ call ebx ;call rbx
+ ret
+EnableLongMode endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
new file mode 100644
index 0000000..8b3cd2a
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
@@ -0,0 +1,78 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableMachineCheck.asm 1 10/01/10 4:56p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 4:56p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;
+; Name: EnableMachineCheck
+;
+; Description:
+; VOID EnableMachineCheck(VOID) sets the Machine Check Exception bit in CR4,
+; which enables machine check interrupts to occur.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;*************************************************************************
+_EnableMachineCheck proc
+ mov eax, cr4
+ or eax, 1 SHL 6
+ mov cr4, eax
+ ret
+_EnableMachineCheck endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32CLib.c b/Core/CPU/IA32/IA32CLib.c
new file mode 100644
index 0000000..4cf579c
--- /dev/null
+++ b/Core/CPU/IA32/IA32CLib.c
@@ -0,0 +1,1959 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c 14 11/11/11 3:39p Artems $
+//
+// $Revision: 14 $
+//
+// $Date: 11/11/11 3:39p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c $
+//
+// 14 11/11/11 3:39p Artems
+// Bug fix: Verify pointer is not NULL when return value
+//
+// 13 10/18/11 11:47a Yakovlevs
+// [TAG] EIP71694
+// [Category] Bug Fix
+// [Symptom] Option ROM is corrupted when copied from device on Rosecity
+// Core 4.6.5.1.
+// [RootCause] MemCpy was updated to use 8 bytes at a time.
+// PCI ROM BAR was not able to handle this type of request.
+// [Solution] Introducesd MemCpy32 functiom.
+// [Files] AmiLib.h; AmiX64Lib.cif; IA32CLib.c
+// MemCpy32.asm - added
+//
+// 12 10/01/10 4:57p Felixp
+// Most of the functions from IA32AsmLib.asm moved here
+//
+// 11 11/25/09 1:55p Felixp
+//
+// 10 11/24/09 5:24p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support. InitLongMode function modified.
+//
+// 9 11/05/09 5:03p Oleksiyy
+// EIP 27821 Support for 64 bit operations in IoRead and IoWrite added.
+//
+// 8 7/10/09 9:26a Felixp
+// Function headers are added
+//
+// 7 4/17/08 2:30p Markw
+// Update InitLongMode to create pages above 32-bits.
+//
+// 6 3/24/08 2:18p Markw
+// Added support for pages tables above 4GB. Currently, disabled.
+//
+// 5 3/18/08 2:41p Markw
+// Update page table for first 2MB to have 4k pages. This is so cache
+// attributes will not be different in a page.
+//
+// 4 4/25/07 5:36p Felixp
+// InitLongMode and EnableLongMode routines extended so support calling of
+// the x64 routine with 2 parameters
+//
+// 3 12/28/06 6:21p Felixp
+// VC8 32-bit compiler support added
+//
+// 2 10/09/06 10:09a Felixp
+// Clean up
+//
+// 1 8/24/06 12:54p Felixp
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: IA32CLib.c
+//
+// Description:
+// Generic CPU library functions for the IA32 architecture. See function
+// definitions in the x64 library; most IA32 functions have been removed
+// from help builder output to fix a name collision issue.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <PEI.h>
+#include <AmiLib.h>
+#include <Hob.h>
+
+//*************************************************************************
+// Math
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: Shr64
+//
+// Description:
+// UINT64 Shr64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// right the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted.
+//
+// IN UINT8 Shift
+// The number of bits to shift right.
+//
+// Output:
+// UINT64 Value shifted right Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shr64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov eax, edx
+ xor edx, edx
+less_32:
+ shrd eax, edx, cl
+ shr edx, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Shl64
+//
+// Description:
+// UINT64 Shl64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// left the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted left.
+//
+// IN UINT8 Shift
+// The number of bits to shift.
+//
+// Output:
+// UINT64 Value shifted left Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shl64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov edx, eax
+ xor eax, eax
+less_32:
+ shld edx, eax, cl
+ shl eax, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Div64
+//
+// Description:
+// UINT64 Div64(IN UINT64 Dividend, IN UINTN Divisor,
+// OUT UINTN *Remainder OPTIONAL) divides a 64-bit number, Dividend, by the
+// Divisor, which can be up to 31-bits.
+//
+// Input:
+// IN UINT64 Dividend
+// The 64-bit number to be divided.
+//
+// IN UINT Divisor
+// The number to divide Dividend by; may not exceed 31-bits in size.
+//
+// OUT UINTN *Remainder OPTIONAL
+// The remainder of the division. Provide NULL if undesired; otherwise user
+// is responsible for handling the necessary memory resources.
+//
+// Output:
+// UINT64 result of dividing Dividend by Divisor.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Div64 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result;
+ UINT32 Rem;
+ _asm
+ {
+ mov eax, dword ptr Dividend[0]
+ mov edx, dword ptr Dividend[4]
+ mov esi, Divisor
+ xor edi, edi ; Remainder
+ mov ecx, 64 ; 64 bits
+Div64_loop:
+ shl eax, 1 ;Shift dividend left. This clears bit 0.
+ rcl edx, 1
+ rcl edi, 1 ;Shift remainder left. Bit 0 = previous dividend bit 63.
+
+ cmp edi, esi ; If Rem >= Divisor, don't adjust
+ cmc ; else adjust dividend and subtract divisor.
+ sbb ebx, ebx ; if Rem >= Divisor, ebx = 0, else ebx = -1.
+ sub eax, ebx ; if adjust, bit 0 of dividend = 1
+ and ebx, esi ; if adjust, ebx = Divisor, else ebx = 0.
+ sub edi, ebx ; if adjust, subtract divisor from remainder.
+ loop Div64_loop
+
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov Rem, edi
+ }
+
+ if (Remainder) *Remainder = Rem;
+
+ return Result;
+}
+//*************************************************************************
+//
+// Name: Mul64
+//
+// Description:
+// UINT64 Mul64(IN UINT64 Value64, IN UINTN Value32) multiplies a 64-bit
+// number by a 32-bit number and returns the 64-bit result.
+//
+// Input:
+// IN UINTN64 Value64
+// The 64-bit number to multiply by.
+//
+// IN UINTN Value32
+// The 32-bit number to multiply by.
+//
+// Output:
+// UINT64 result of multiplying Value64 by Value32.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Mul64(
+ IN UINT64 Value64,
+ IN UINTN Value32
+ )
+{
+ UINT64 Result;
+
+ _asm {
+ mov eax, dword ptr Value64[0]
+ mul Value32
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov eax, dword ptr Value64[4]
+ mul Value32
+ add dword ptr Result[4], eax
+ }
+
+ return Result;
+}
+
+//*************************************************************************
+// Memory Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: MemCpy
+//
+// Description:
+// VOID MemCpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+// copies Count bytes of memory from Source to Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This function checks for overlapping of source and destination and
+// selects copy direction that prevents memory corruption.
+//
+//*************************************************************************
+VOID MemCpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ _asm{
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ pushf
+ mov esi, pSource
+ mov edi, pDestination
+ mov ecx, Count
+ mov dl, 0
+ mov eax, esi
+ sub eax, edi
+ jnb CopyForward
+ lea ebx, [esi+ecx]
+ neg eax
+ cmp ebx, edi
+ jb CopyForward
+ mov esi, ebx
+ lea edi, [edi+ecx]
+ mov dl, 1
+ std
+CopyForward:
+ cmp ecx, 4
+ jb m8
+ cmp eax, 4
+ jb m8
+ mov eax, esi
+ mov ebx, edi
+ and eax, 3
+ and ebx, 3
+ test dl, dl
+ jz skip1
+ dec esi
+ dec edi
+skip1:
+ cmp eax, ebx
+ jne m32
+ test eax, eax
+ jz m32
+ test dl, dl
+ jnz skip_nz1
+ neg eax
+ add eax, 4
+skip_nz1:
+ xchg eax, ecx
+ sub eax, ecx
+ rep movsb
+ mov ecx, eax
+m32:
+ test dl, dl
+ jz skip2
+ sub esi, 3
+ sub edi, 3
+skip2:
+ mov eax, ecx
+ shr ecx, 2
+ rep movsd
+ and eax, 3
+ jz end
+ test dl, dl
+ jz skip3
+ add esi, 4
+ add edi, 4
+skip3:
+ mov ecx, eax
+m8:
+ test dl, dl
+ jz skip4
+ dec esi
+ dec edi
+skip4:
+ rep movsb
+end:
+ popf
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+VOID MemCpy32(VOID* pDestination, VOID* pSource, UINTN Count){
+ MemCpy(pDestination, pSource, Count);
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: memcpy
+//
+// Description:
+// VOID memcpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count) is
+// a wrapper for MemCpy, which copies Count bytes of memory from Source to
+// Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// MemCpy
+//
+// Notes:
+// MemCpy checks for overlapping of source and destination and selects copy
+// direction that prevents memory corruption.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID memcpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ MemCpy(pDestination,pSource,Count);
+}
+
+//*************************************************************************
+//
+// Name: MemSet
+//
+// Description:
+// VOID MemSet(IN VOID *pBuffer, IN UINTN Count, IN UINT8 Value) fills Count
+// bytes of memory in pBuffer with Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemSet(VOID* pBuffer, UINTN Count, UINT8 Value)
+{
+ _asm{
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ // fill EAX with the Value so that we can perform DWORD operatins
+ mov al,Value
+ mov ah, al
+ mov bx,ax
+ shl eax,16
+ mov ax,bx
+ mov edi, pBuffer
+ // if Counter is less then 4, jump to byte copy
+ mov ecx, Count
+ cmp ecx, 4
+ jb CopyByte
+ // check if the Buffer is 4-bytes aligned
+ mov edx,edi
+ and edx, 3
+ // if the Buffer is 4-bytes aligned, jump to DWORD copy
+ jz CopyDword
+ // Buffer is not 4-bytes aligned
+ // Calculate 4-(Buffer%4), which is a number of bytes we have to copy before
+ // Buffer will reach 4-bytes boundary, and perform byte copy
+ neg edx
+ add edx, 4
+ xchg ecx, edx
+ sub edx, ecx
+ rep stosb
+ mov ecx, edx
+CopyDword:
+ // perform DWORD copy
+ mov edx, ecx
+ shr ecx, 2
+ rep stosd
+ // copy the remainder
+ and edx,3
+ mov ecx, edx
+CopyByte:
+ rep stosb
+ ///
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+//*************************************************************************
+//
+// Name: memset
+//
+// Description:
+// VOID memset(IN VOID *pBuffer, IN UINT8 Value, IN UINTN Count) is a
+// wrapper for MemSet which fills Count bytes of memory in pBuffer with
+// Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID memset(VOID* pBuffer, UINTN Value, UINTN Count)
+{
+ MemSet(pBuffer,Count,(UINT8)Value);
+}
+//*************************************************************************
+// Debug routines
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: checkpoint
+//
+// Description:
+// VOID checkpoint(IN UINT8 c) writes the value c to port 0x80.
+//
+// Input:
+// IN UINT8 c
+// The value/checkpoint to write to 0x80.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This routine should only be used if the PROGRESS_CODE or
+// PEI_PROGRESS_CODE macros are unavailable.
+//
+//*************************************************************************
+VOID checkpoint(UINT8 c){
+ _asm{
+ mov al, c
+ out 0x80,al
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCpuTimer
+//
+// Description:
+// UINT64 GetCpuTimer() returns the value of the CPU timer.
+//
+// Input:
+// None.
+//
+// Output:
+// UINT64 value of the CPU timer.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetCpuTimer(){_asm rdtsc}
+
+//*************************************************************************
+// I/O Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: IoRead8
+//
+// Description:
+// UINT8 IoRead8(IN UINT16 Port) reads the 8-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 8-bits from.
+//
+// Output:
+// UINT8 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT8 IoRead8(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in al, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite8
+//
+// Description:
+// VOID IoWrite8(IN UINT16 Port, IN UINT8 Value) writes the 8-bit Value to
+// the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 8-bits to.
+//
+// IN UINT8 Value
+// 8-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite8(UINT16 Port,UINT8 Value)
+{
+ _asm {
+ mov dx, Port
+ mov al, Value
+ out dx, al
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead16
+//
+// Description:
+// UINT16 IoRead16(IN UINT16 Port) reads the 16-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 16-bits from.
+//
+// Output:
+// UINT16 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 IoRead16(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in ax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite16
+//
+// Description:
+// VOID IoWrite16(IN UINT16 Port, IN UINT16 Value) writes the 16-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 16-bits to.
+//
+// IN UINT16 Value
+// 16-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite16(UINT16 Port,UINT16 Value)
+{
+ _asm {
+ mov dx, Port
+ mov ax, Value
+ out dx, ax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead32
+//
+// Description:
+// UINT32 IoRead32(IN UINT16 Port) reads the 32-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 IoRead32(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in eax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite32
+//
+// Description:
+// VOID IoWrite32(IN UINT16 Port, IN UINT32 Value) writes the 32-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 32-bits to.
+//
+// IN UINT32 Value
+// 32-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite32(UINT16 Port,UINT32 Value)
+{
+ _asm {
+ mov dx, Port
+ mov eax, Value
+ out dx, eax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead64
+//
+// Description:
+// UINT32 IoRead64(IN UINT16 Port) reads the 64-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 64-bits from.
+//
+// Output:
+// UINT64 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 IoRead64(UINT16 Port)
+{
+
+ UINT64 Result;
+ UINT64 *Buffer = &Result;
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ in eax, dx
+ mov dword ptr[esi],eax
+ add esi, 4
+ add dx, 4
+ in eax, dx
+ mov dword ptr[esi],eax
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: IoWrite64
+//
+// Description:
+// VOID IoWrite64(IN UINT16 Port, IN UINT64 Value) writes the 64-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 64-bits to.
+//
+// IN UINT64 Value
+// 64-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite64(UINT16 Port, UINT64 Value)
+{
+// UINT32 Lo=(UINT32)Value, Hi=(UINT32)Shr64(Value,32);
+
+ VOID* Buffer=&Value;
+
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ mov eax, dword ptr[esi]
+ out dx, eax
+ add esi, 4
+ add dx, 4
+ mov eax, dword ptr[esi]
+ out dx, eax
+ }
+
+
+
+}
+
+VOID EnableLongMode(VOID *PageTable, VOID *Function, VOID *Parameter1, VOID *Parameter2);
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongModeExt
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongModeExt(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2,
+ IN UINT8 NumMemBits
+)
+{
+ EFI_PHYSICAL_ADDRESS PageTable;
+ UINT32 NumPages;
+ EFI_STATUS Status;
+//TODO: In AllocatePages below, change EfiACPIMemoryNVS to EfiBootServicesData.
+//TODO: It is left as EfiACPIMemoryNVS until future projects can be updated to
+//TODO: a later CPU module. Future CPU modules will allocate EfiACPIMemoryNVS
+//TODO: for only 32-bits.
+
+ NumPages = GetPageTableNumPages(NumMemBits);
+
+ Status = (*PeiServices)->AllocatePages(
+ PeiServices,
+ EfiACPIMemoryNVS,
+ NumPages,
+ &PageTable
+ );
+ //ASSERT_PEI_ERROR(PeiServices,Status);
+
+ FillPageTable(NumMemBits, (VOID*)PageTable);
+
+ EnableLongMode((VOID*)PageTable, Function, Parameter1, Parameter2);
+}
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongMode
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2
+)
+{
+
+
+ UINT8 NumMemBits = 32;
+ EFI_HOB_CPU *CpuHob;
+ VOID *FirstHob;
+ EFI_STATUS Status;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ //if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ CpuHob = (EFI_HOB_CPU*) FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &CpuHob);
+
+ //If error during release mode, The memory cache size will be 32-bits.
+ //During debug mode, an assert will happen to alert that the CPU HOB is
+ //not produced, so that all memory will not be paged.
+ //ASSERT_PEI_ERROR(PeiServices, Status);
+
+ //Find APIC ID Hob.
+ if (!EFI_ERROR(Status)) {
+ NumMemBits = CpuHob->SizeOfMemorySpace;
+ }
+
+ InitLongModeExt (PeiServices, Function, Parameter1, Parameter2, NumMemBits);
+}
+
+//*************************************************************************
+//
+// Name: GetPowerOfTwo64
+//
+// Description:
+// UINT64 GetPowerOfTwo64(IN UINT64 Input) returns the highest bit set in
+// the provided UINT64 Input. Equivalent to 1 << log2(x).
+//
+// Input:
+// IN UINT64 Input
+// The 64-bit value to check for its highest bit.
+//
+// Output:
+// UINT64 value of the highest bit; if Input is 0, returns 0.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetPowerOfTwo64(
+ IN UINT64 Input
+)
+{
+ UINT64 Result = 0;
+
+ if (Input > 0xffffffff) {
+ _asm {
+ bsr eax, dword ptr Input[4]
+ bts dword ptr Result[4], eax
+ }
+ } else {
+ _asm {
+ bsr eax, dword ptr Input[0]
+ bts dword ptr Result[0], eax
+ }
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: ReadMsr
+//
+// Description:
+// UINT64 ReadMsr(IN UINT32 Msr) reads the CPU MSR index defined by Msr and
+// returns the value.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be read.
+//
+// Output:
+// UINT64 MSR value at MSR index, Msr.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadMsr(IN UINT32 Msr){
+ _asm{
+ mov ecx, Msr ;MSR register
+ rdmsr
+ }
+}
+
+//*************************************************************************
+//
+// Name: WriteMsr
+//
+// Description:
+// VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value) writes the Value to the
+// supplied MSR index, Msr.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be written to.
+//
+// IN UINT64 Value
+// Value to be written to MSR index.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value){
+ _asm{
+ mov ecx, Msr ;MSR register
+ mov edx, dword ptr Value[4] ;Upper 32 bit MSR Value
+ mov eax, dword ptr Value[0] ;Lower 32 bit MSR Value
+ wrmsr
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_CpuID
+//
+// Description:
+// VOID CPULib_CpuID(IN UINT32 CpuIDIndex, IN OUT UINT32 *pRegEAX,
+// IN OUT UINT32 *pRegEBX, IN OUT UINT32 *pRegECX, IN OUT UINT32 *pRegEDX)
+// issues the CPUID instruction with the index provided and returns the
+// register values.
+//
+// Input:
+// IN UINT32 CpuIDIndex
+// 32-bit CPUID index.
+//
+// IN OUT UINT32 *pRegEAX
+// Pointer to UINT32 for EAX return value.
+//
+// IN OUT UINT32 *pRegEBX
+// Pointer to UINT32 for EBX return value.
+//
+// IN OUT UINT32 *pRegECX
+// Pointer to UINT32 for ECX return value.
+//
+// IN OUT UINT32 *pRegEDX
+// Pointer to UINT32 for EDX return value.
+//
+// Output:
+// IN OUT UINT32 *pRegEAX
+// Value of EAX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEBX
+// Value of EBX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegECX
+// Value of ECX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEDX
+// Value of EDX after CPUID instruction.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_CpuID(
+ IN UINT32 CpuIDIndex,
+ IN OUT UINT32 *pRegEAX,
+ IN OUT UINT32 *pRegEBX,
+ IN OUT UINT32 *pRegECX,
+ IN OUT UINT32 *pRegEDX)
+{
+ _asm{
+ push ebx
+ push ecx
+ push edx
+ push esi
+ mov esi, pRegECX
+ mov ecx, [esi]
+ mov eax, CpuIDIndex
+ cpuid
+ mov esi, pRegEAX
+ or esi, esi
+ jz skip1
+ mov [esi], eax
+skip1:
+ mov esi, pRegEBX
+ or esi, esi
+ jz skip2
+ mov [esi], ebx
+skip2:
+ mov esi, pRegECX
+ or esi, esi
+ jz skip3
+ mov [esi], ecx
+skip3:
+ mov esi, pRegEDX
+ or esi, esi
+ jz skip4
+ mov [esi], edx
+skip4:
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: DisableCacheInCR0
+//
+// Description:
+// VOID DisableCacheInCR0(VOID) disables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID DisableCacheInCR0(VOID){
+ _asm{
+ wbinvd
+ mov eax, cr0
+ or eax, 060000000h ;SET CD, NW
+ mov cr0, eax
+ wbinvd ;Invalidate cache
+ }
+}
+
+//*************************************************************************
+//
+// Name: EnableCacheInCR0
+//
+// Description:
+// VOID EnableCacheInCR0(VOID) enables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID EnableCacheInCR0(VOID){
+ _asm{
+ // Enable cache
+ mov eax, cr0
+ and eax, 09fffffffh ;SET CD, NW
+ mov cr0, eax
+ wbinvd
+ }
+}
+//*************************************************************************
+//
+// Name: ReadCr3
+//
+// Description:
+// UINTN ReadCr3(VOID) reads the register CR3 and returns its value.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINTN value stored in the CR3 register.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINTN ReadCr3(VOID){
+ _asm{
+ mov eax, cr3
+ }
+}
+//*************************************************************************
+//
+// Name: WriteCr3
+//
+// Description:
+// VOID WriteCr3(IN UINTN CR3) writes the provided value to the CR3 register.
+//
+// Input:
+// IN UINTN CR3
+// Value to be written to the CR3 register.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteCr3(IN UINTN CR3){
+ _asm{
+ mov eax, CR3
+ mov cr3, eax
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_EnableInterrupt
+//
+// Description:
+// VOID CPULib_EnableInterrupt(VOID) enables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_EnableInterrupt(VOID){
+ _asm{
+ // Enable Interrupt
+ sti
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_DisableInterrupt
+//
+// Description:
+// VOID CPULib_DisableInterrupt() disables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_DisableInterrupt(){
+ _asm{
+ // Disable Interrupt
+ cli
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_GetInterruptState
+//
+// Description:
+// BOOLEAN CPULib_GetInterruptState(VOID)returns the current CPU interrupt
+// state.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns FALSE if interrupts are disabled; otherwise TRUE.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+BOOLEAN CPULib_GetInterruptState(VOID){
+ _asm{
+ xor bl, bl
+ pushfd ; push flags onto stack.
+ pop eax ; eax = flags.
+ bt eax,9 ; IF (bit 9) if set, set carry flag.
+ ; Interrupts are allowed if IF is set.
+ adc bl, 0 ; BL = IF = CF.
+
+ mov al, bl ; Return value
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCsSegment
+//
+// Description:
+// UINT16 GetCsSegment(VOID) retreives the value of the CS register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT16 value of CS.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 GetCsSegment(VOID){
+ _asm{
+ mov ax, cs
+ }
+}
+
+//*************************************************************************
+//
+// Name: ReadRtdsc
+//
+// Description:
+// UINT64 ReadRtdsc(VOID) retrieves the time stamp counter.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT64 value of the time stamp counter.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadRtdsc(VOID){
+ _asm{
+ rdtsc
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForever
+//
+// Description:
+// VOID WaitForever(VOID) performs an infinite loop which does nothing.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForever(VOID){
+ _asm{
+ bbb:
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: HltCpu
+//
+// Description:
+// VOID HltCpu(VOID) halts the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID HltCpu(VOID){
+ _asm{
+ bbb:
+ cli
+ hlt
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_Pause
+//
+// Description:
+// VOID CPULib_Pause(VOID) performs the pause assembly instruction.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_Pause(VOID){
+ _asm{
+ pause
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForSemaphore
+//
+// Description:
+// VOID WaitForSemaphore(IN volatile UINT8 *Semaphore) waits for the
+// semaphore to become available; once available, it claims the semaphore and
+// returns.
+//
+// Input:
+// IN volatile UINT8 *Semaphore
+// Pointer to the desired semaphore.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForSemaphore(IN volatile UINT8 *Semaphore){
+ _asm{
+ push ebx
+ mov al, 1
+ mov ebx, Semaphore
+ bbb:
+ xchg al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero8
+//
+// Description:
+// VOID WaitUntilZero8(IN volatile UINT8 *Value) waits until the byte stored
+// at Value becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT8 *Value
+// Address of the byte value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero8(IN volatile UINT8 *Value){
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero32
+//
+// Description:
+// VOID WaitUntilZero32(IN volatile UINT32 *Value) waits until the UINT32
+// value stored at the Value address becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT32 *Value
+// Address of the UINT32 value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero32(IN volatile UINT32 *Value) {
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov eax, [ebx]
+ or eax, eax
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteInc
+//
+// Description:
+// VOID CPULib_LockByteInc(IN UINT8 *ptr) locks the next byte after the
+// address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr// Address to the byte which preceeds the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteInc(IN UINT8 *xptr){
+ _asm{
+ mov eax, xptr
+ lock inc byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteDec
+//
+// Description:
+// VOID CPULib_LockByteDec(IN UINT8 *ptr) locks the preceeding byte before
+// the address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr
+// Address to the byte which follows the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteDec(IN UINT8 *xptr) {
+ _asm{
+ mov eax, xptr
+ lock dec byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadGdt
+//
+// Description:
+// VOID CPULib_LoadGdt(IN VOID *ptr) loads the GDT at the location pointed to
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the GDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveGdt
+//
+// Description:
+// VOID CPULib_SaveGdt(IN VOID *ptr) stores the loaded GDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the GDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadIdt
+//
+// Description:
+// VOID CPULib_LoadIdt(IN VOID *ptr) loads the IDT at the location provided
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the IDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveIdt
+//
+// Description:
+// VOID CPULib_SaveIdt(IN VOID *ptr) stores the loaded IDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the IDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemRead32
+//
+// Description:
+// UINT32 MemRead32(IN UINT32 *Address) reads and returns the 32-bit value
+// stored at the user provided address.
+//
+// Input:
+// IN UINT32 *Address
+// Address to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at Address.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 MemRead32(IN UINT32 *Address) {
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ pop esi
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemReadWrite32
+//
+// Description:
+// VOID MemReadWrite32(IN UINT32 *Address, IN UINT32 Value, IN UINT32 Mask)
+// reads the 32-bit value stored at Address, ANDs it with Mask, ORs the result
+// with Value, then writes the result back to Address.
+//
+// Input:
+// IN UINT32 *Address
+// Address which shall be read from and subsequently written to.
+//
+// IN UINT32 Value
+// Value to be ORed with the value stored at Address after it has been ANDed
+// with the provided Mask.
+//
+// IN UINT32 Mask
+// Mask to be ANDed with the original value stored at Address.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemReadWrite32(
+ IN UINT32 *Address,
+ IN UINT32 Value,
+ IN UINT32 Mask)
+{
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ and eax, Mask ;Mask
+ or eax, Value ;Value
+ mov [esi], eax
+ pop esi
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/IA32/IA32Core.cif b/Core/CPU/IA32/IA32Core.cif
new file mode 100644
index 0000000..352c150
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "IA32 Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "IA32Core"
+[files]
+"IA32Core.sdl"
+"IA32rules.mak"
+<endComponent>
diff --git a/Core/CPU/IA32/IA32Core.sdl b/Core/CPU/IA32/IA32Core.sdl
new file mode 100644
index 0000000..98f179a
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "IA32Core_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IA32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "AFLAGSIA32"
+ Value = "/coff"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "IA32Core_DIR"
+End
+
+ELINK
+ Name = "IA32"
+ Parent = "PROCESSOR"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IA32Core_DIR)\IA32rules.mak"
+ Parent = "PROCESSOR_RULES"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CPU/IA32/IA32rules.mak b/Core/CPU/IA32/IA32rules.mak
new file mode 100644
index 0000000..8f58110
--- /dev/null
+++ b/Core/CPU/IA32/IA32rules.mak
@@ -0,0 +1,62 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak 2 12/28/06 6:22p Felixp $
+#
+# $Revision: 2 $
+#
+# $Date: 12/28/06 6:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak $
+#
+# 2 12/28/06 6:22p Felixp
+# VC8 32-bit compiler support added
+#
+# 1 10/13/06 8:30p Felixp
+#
+# 1 8/24/06 12:54p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IA32rules.mak
+#
+# Description: Defines IA32-specific build rules.
+# This file is included into the template makefile rules.mak
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(TOOLS)"=="vc8"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /GS-
+!ENDIF
+
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) $(CFLAGSIA32)
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) $(LFLAGSIA32)
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) $(AFLAGSIA32)
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.c b/Core/CPU/IA32/PeCoffLoaderEx.c
new file mode 100644
index 0000000..3e08c1c
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.c
@@ -0,0 +1,93 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) ||
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.h b/Core/CPU/IA32/PeCoffLoaderEx.h
new file mode 100644
index 0000000..a83282d
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IA32/Processor.c b/Core/CPU/IA32/Processor.c
new file mode 100644
index 0000000..fcdd4bf
--- /dev/null
+++ b/Core/CPU/IA32/Processor.c
@@ -0,0 +1,140 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+TransferControlSetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+TransferControlLongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+//
+// Table declarations
+//
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ TransferControlSetJump,
+ TransferControlLongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ FlushInstructionCacheFlush
+};
+
+
+EFI_STATUS
+InstallEfiPeiTransferControl (
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+ In the case of IA32, this flushing is not necessary and is thus not implemented.
+
+Arguments:
+
+ This - Pointer to CPU Architectural Protocol interface
+ Start - Start adddress in memory to flush
+ Length - Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/IA32/Processor.h b/Core/CPU/IA32/Processor.h
new file mode 100644
index 0000000..0084d4a
--- /dev/null
+++ b/Core/CPU/IA32/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the IA-32 processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
+
+#endif \ No newline at end of file
diff --git a/Core/CPU/IA32/ProcessorAsms.Asm b/Core/CPU/IA32/ProcessorAsms.Asm
new file mode 100644
index 0000000..86f4606
--- /dev/null
+++ b/Core/CPU/IA32/ProcessorAsms.Asm
@@ -0,0 +1,223 @@
+;
+; Copyright (c) 2004, Intel Corporation
+; All rights reserved. This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+; ProcessorAsms.Asm
+;
+; Abstract:
+; This is separated from processor.c to allow this functions to be built with /O1
+;
+; Notes:
+; - Masm uses "This", "ebx", etc as a directive.
+; - H2INC is still not embedded in our build process so I translated the struc manually.
+; - Unreferenced variables/arguments (This, NewBsp, NewStack) were causing compile errors and
+; did not know of "pragma" mechanism in MASM and I did not want to reduce the warning level.
+; Instead, I did a dummy referenced.
+;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+EFI_SUCCESS equ 0
+EFI_WARN_RETURN_FROM_LONG_JUMP equ 5
+
+;
+; Generated by h2inc run manually
+;
+_EFI_JUMP_BUFFER STRUCT 2t
+_ebx DWORD ?
+_esi DWORD ?
+_edi DWORD ?
+_ebp DWORD ?
+_esp DWORD ?
+_eip DWORD ?
+_EFI_JUMP_BUFFER ENDS
+
+EFI_JUMP_BUFFER TYPEDEF _EFI_JUMP_BUFFER
+
+TransferControlSetJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+TransferControlLongJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+SwitchStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+SwitchIplStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+;
+;Routine Description:
+;
+; This routine implements the IA32 variant of the SetJump call. Its
+; responsibility is to store system state information for a possible
+; subsequent LongJump.
+;
+;Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+;Returns:
+;
+; EFI_SUCCESS
+;
+TransferControlSetJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ mov eax, _This
+ mov ecx, Jump
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebx, ebx
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esi, esi
+ mov (EFI_JUMP_BUFFER PTR [ecx])._edi, edi
+ mov eax, [ebp]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebp, eax
+ lea eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esp, eax
+ mov eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._eip, eax
+ mov eax, EFI_SUCCESS
+
+ ret
+
+TransferControlSetJump ENDP
+
+;
+; Routine Description:
+;
+; This routine implements the IA32 variant of the LongJump call. Its
+; responsibility is restore the system state to the Context Buffer and
+; pass control back.
+;
+; Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+; Returns:
+;
+; EFI_WARN_RETURN_FROM_LONG_JUMP
+;
+
+TransferControlLongJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ push ebx
+ push esi
+ push edi
+
+ mov eax, _This
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov ecx, Jump
+ mov ebx, (EFI_JUMP_BUFFER PTR [ecx])._ebx
+ mov esi, (EFI_JUMP_BUFFER PTR [ecx])._esi
+ mov edi, (EFI_JUMP_BUFFER PTR [ecx])._edi
+ mov ebp, (EFI_JUMP_BUFFER PTR [ecx])._ebp
+ mov esp, (EFI_JUMP_BUFFER PTR [ecx])._esp
+ add esp, 4 ;pop the eip
+ jmp DWORD PTR (EFI_JUMP_BUFFER PTR [ecx])._eip
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+
+ pop edi
+ pop esi
+ pop ebx
+ ret
+
+TransferControlLongJump ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+ push ebx
+ push 0
+ jmp ecx
+
+ pop ebx
+ ret
+
+SwitchStacks ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter1/Parameter2 - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchIplStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter1
+ mov edx, Parameter2
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+
+ push edx
+ push ebx
+ call ecx
+
+ pop ebx
+ ret
+
+SwitchIplStacks ENDP
+
+ END
+
diff --git a/Core/CPU/IA32/SwitchCoreStacks.asm b/Core/CPU/IA32/SwitchCoreStacks.asm
new file mode 100644
index 0000000..dbb664d
--- /dev/null
+++ b/Core/CPU/IA32/SwitchCoreStacks.asm
@@ -0,0 +1,104 @@
+ TITLE SwitchCoreStacks.asm: Core stack switching routine
+
+;------------------------------------------------------------------------------
+;Copyright (c) 2004, Intel Corporation
+;All rights reserved. This program and the accompanying materials
+;are licensed and made available under the terms and conditions of the BSD License
+;which accompanies this distribution. The full text of the license may be found at
+;http://opensource.org/licenses/bsd-license.php
+;
+;THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;Module Name:
+;
+; SwitchCoreStacks.asm
+;
+;Abstract:
+;
+; Core stack switching routine, invoked when real system memory is
+; discovered and installed.
+;
+;------------------------------------------------------------------------------
+
+ .686P
+ .XMM
+ .MODEL SMALL
+ .CODE
+
+
+include token.equ
+
+AsmWriteMm7 PROTO C
+
+AsmWriteMm7 PROC C
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmWriteMm7 (
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+ movq mm7, [esp + 4]
+ ret
+AsmWriteMm7 ENDP
+
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+ELSE
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+ENDIF
+
+;------------------------------------------------------------------------------
+; VOID
+; SwitchCoreStacks (
+; IN VOID *EntryPoint,
+; IN UINTN Parameter1,
+; IN UINTN Parameter2,
+; IN UINTN Parameter3,
+; IN VOID *NewStack
+; )
+;
+; Routine Description:
+;
+; Routine for PEI switching stacks.
+;
+; Arguments:
+;
+; EntryPoint - Entry point with new stack.
+; Parameter1 - First parameter for entry point.
+; Parameter2 - Second parameter for entry point.
+; Parameter3 - Third parameter for entry point.
+; NewStack - Pointer to new stack.
+;
+; Returns:
+;
+; None
+;
+;----------------------------------------------------
+
+ mov ebx, Parameter1
+ mov edx, Parameter2
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ mov eax, Parameter3
+ENDIF
+ mov ecx, EntryPoint
+ mov esp, NewStack
+
+ ; First push Parameter3, and then Parameter2 ,at last Parameter1.
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ push eax
+ENDIF
+ push edx
+ push ebx
+ call ecx
+
+ ret
+
+SwitchCoreStacks ENDP
+
+END
diff --git a/Core/CPU/IA32/efijump.h b/Core/CPU/IA32/efijump.h
new file mode 100644
index 0000000..d676f88
--- /dev/null
+++ b/Core/CPU/IA32/efijump.h
@@ -0,0 +1,34 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an IA32 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+typedef struct {
+ UINT32 ebx;
+ UINT32 esi;
+ UINT32 edi;
+ UINT32 ebp;
+ UINT32 esp;
+ UINT32 eip;
+} EFI_JUMP_BUFFER;
+
+#endif
diff --git a/Core/CPU/IPF/FoundationIPF.cif b/Core/CPU/IPF/FoundationIPF.cif
new file mode 100644
index 0000000..c6f8c63
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "FoundationIPF"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IPF\"
+ RefName = "FoundationIPF"
+[files]
+"FoundationIPF.sdl"
+"FoundationIPF.mak"
+"SwitchStack.s"
+"asm.h"
+"efijump.h"
+"ia_64gen.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"PerformancePrimitives.s"
+"pioflush.s"
+"processor.c"
+"setjmp.s"
+"Processor.h"
+"SwitchToCacheMode.c"
+"IpfCpuCore.s"
+"IpfCpuCore.i"
+
+<endComponent>
diff --git a/Core/CPU/IPF/FoundationIPF.mak b/Core/CPU/IPF/FoundationIPF.mak
new file mode 100644
index 0000000..ad13ce2
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.mak
@@ -0,0 +1,66 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/IPF/FoundationIPF.mak 1 8/24/06 12:37p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:37p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/IPF/FoundationIPF.mak $
+#
+# 1 8/24/06 12:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FoundationIPF.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+FoundationIPF : $(BUILD_DIR)\FoundationIPF.mak FoundationIPFBin
+
+$(BUILD_DIR)\FoundationIPF.mak : $(FoundationIPF_DIR)\$(@B).cif $(FoundationIPF_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FoundationIPF_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="IPF"
+FoundationBin : $(BUILD_DIR)\FoundationIPF.lib
+FoundationPeiBin : $(BUILD_DIR)\FoundationIPF.lib
+$(BUILD_DIR)\FoundationIPF.lib : FoundationIPF
+!ENDIF
+
+
+FoundationIPFBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FoundationIPF.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IPF/FoundationIPF.sdl b/Core/CPU/IPF/FoundationIPF.sdl
new file mode 100644
index 0000000..32db6cc
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "FoundationIPF_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FoundationIPF support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FoundationIPF_DIR"
+End
+
+MODULE
+ Help = "Includes FoundationIPF.mak to Project"
+ File = "FoundationIPF.mak"
+End
+
diff --git a/Core/CPU/IPF/IpfCpuCore.i b/Core/CPU/IPF/IpfCpuCore.i
new file mode 100644
index 0000000..d0c6fa2
--- /dev/null
+++ b/Core/CPU/IPF/IpfCpuCore.i
@@ -0,0 +1,93 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// IpfCpuCore.i
+//
+// Abstract:
+// IPF CPU definitions
+//
+//--
+
+#ifndef _IPF_CPU_CORE_
+#define _IPF_CPU_CORE_
+
+#define PEI_BSP_STORE_SIZE 0x4000
+#define ResetFn 0x00
+#define MachineCheckFn 0x01
+#define InitFn 0x02
+#define RecoveryFn 0x03
+#define GuardBand 0x10
+
+//
+// Define hardware RSE Configuration Register
+//
+
+//
+// RS Configuration (RSC) bit field positions
+//
+#define RSC_MODE 0
+#define RSC_PL 2
+#define RSC_BE 4
+//
+// RSC bits 5-15 reserved
+//
+#define RSC_MBZ0 5
+#define RSC_MBZ0_V 0x3ff
+#define RSC_LOADRS 16
+#define RSC_LOADRS_LEN 14
+//
+// RSC bits 30-63 reserved
+//
+#define RSC_MBZ1 30
+#define RSC_MBZ1_V 0x3ffffffffULL
+
+//
+// RSC modes
+//
+
+//
+// Lazy
+//
+#define RSC_MODE_LY (0x0)
+//
+// Store intensive
+//
+#define RSC_MODE_SI (0x1)
+//
+// Load intensive
+//
+#define RSC_MODE_LI (0x2)
+//
+// Eager
+//
+#define RSC_MODE_EA (0x3)
+
+//
+// RSC Endian bit values
+//
+#define RSC_BE_LITTLE 0
+#define RSC_BE_BIG 1
+
+//
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode
+//
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+//
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
+//
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+//
+// RSE disabled: disabled, pl = 0, little endian, eager mode
+//
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+
+#endif
diff --git a/Core/CPU/IPF/IpfCpuCore.s b/Core/CPU/IPF/IpfCpuCore.s
new file mode 100644
index 0000000..d3b7c62
--- /dev/null
+++ b/Core/CPU/IPF/IpfCpuCore.s
@@ -0,0 +1,196 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// IpfCpuCore.s
+//
+// Abstract:
+// IPF Specific assembly routines
+//
+//--
+
+.file "IpfCpuCore.s"
+
+#include "IpfMacro.i"
+#include "IpfCpuCore.i"
+
+//----------------------------------------------------------------------------------
+// This module supports terminating CAR (Cache As RAM) stage. It copies all the
+// CAR data into real RAM and then makes a stack switch.
+
+// EFI_STATUS
+// SwitchCoreStacks (
+// IN VOID *EntryPoint,
+// IN UINTN CopySize,
+// IN VOID *OldBase,
+// IN VOID *NewBase
+// IN UINTN NewSP, OPTIONAL
+// IN UINTN NewBSP OPTIONAL
+// )
+// EFI_STATUS
+// SwitchCoreStacks (
+// IN VOID *EntryPointForContinuationFunction,
+// IN UINTN StartupDescriptor,
+// IN VOID PEICorePointer,
+// IN UINTN NewSP
+// )
+//----------------------------------------------------------------------------------
+PROCEDURE_ENTRY (SwitchCoreStacks)
+
+ NESTED_SETUP (4,2,0,0)
+
+ // first save all stack registers in GPRs.
+ mov r13 = in0;; // this is a pointer to the PLABEL of the continuation function.
+ ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
+ ld8 gp = [r13];; // gp = gp of continuation function from the PLABEL
+ mov b1 = r16;;
+
+ // save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls
+ mov r5 = in1;; // this is the parameter1 to pass to the continuation function
+ mov r6 = in2;; // this is the parameter2 to pass to the continuation function
+ dep r6=0,r6,63,1;; // zero the bit 63.
+
+ mov r8 = in3;; // new stack pointer.
+
+ // r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore
+ movl r15 = PEI_BSP_STORE_SIZE;;
+ sub r8 = r8, r15;;
+ add r15 = (GuardBand),r8;; // some little buffer, now r15 will be our bspstore
+
+ // save the bspstore value to r4, save sp value to r7
+ mov r4 = r15
+ mov r7 = r8
+ mov r16 = r8;; // will be the new sp in uncache mode
+
+
+ alloc r11=0,0,0,0;; // Set 0-size frame
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
+ mov ar.rsc = r21;; // turn off RSE
+
+ add sp = r0, r16 // transfer to the EFI stack
+ mov ar.bspstore = r15 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
+ mov ar.rsc = r19;; // turn rse on, in kernel mode
+
+//-----------------------------------------------------------------------------------
+// Save here the meaningful stuff for next few lines and then make the PAL call.
+// Make PAL call to terminate the CAR status.
+ // AVL: do this only for recovery check call...
+
+ mov r28=ar.k3;;
+ dep r2 = r28,r0,0,8;; // Extract Function bits from GR20.
+ cmp.eq p6,p7 = RecoveryFn,r2;; // Is it Recovery check
+ (p7) br.sptk.few DoneCARTermination; // if not, don't terminate car..
+
+TerminateCAR::
+
+ mov r28 = ip;;
+ add r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;
+ mov b0 = r28
+
+ mov r8 = ar.k5;;
+ mov b6 = r8
+ mov r28 = 0x208
+
+ mov r29 = r0
+ mov r30 = r0
+ mov r31 = r0
+ mov r8 = r0;;
+ br.sptk.few b6;; // Call PAL-A call.
+
+DoneCARTerminationPALCall::
+
+// don't check error in soft sdv, it is always returning -1 for this call for some reason
+#if SOFT_SDV
+#else
+ReturnToPEIMain::
+ cmp.eq p6,p7 = r8,r0;;
+ //
+ // dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory
+ //
+ (p7) br.sptk.few ReturnToPEIMain;;
+ //
+ // PAL call successed,now the stack are in memory so come into cache mode
+ // instead of uncache mode
+ //
+
+ alloc r11=0,0,0,0;; // Set 0-size frame
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
+ mov ar.rsc = r21;; // turn off RSE
+
+ dep r6 = 0,r6,63,1 // zero the bit 63
+ dep r7 = 0,r7,63,1 // zero the bit 63
+ dep r4 = 0,r4,63,1;; // zero the bit 63
+ add sp = r0, r7 // transfer to the EFI stack in cache mode
+ mov ar.bspstore = r4 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
+ mov ar.rsc = r19;; // turn rse on, in kernel mode
+
+#endif
+
+DoneCARTermination::
+
+ // allocate a stack frame:
+ alloc r11=0,2,2,0 ;; // alloc outs going to ensuing DXE IPL service
+ // on the new stack
+ mov out0 = r5;;
+ mov out1 = r6;;
+
+ mov r16 = b1;;
+ mov b6 = r16;;
+ br.call.sptk.few b0=b6;; // Call the continuation function
+
+ NESTED_RETURN
+
+PROCEDURE_EXIT(SwitchCoreStacks)
+//-----------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------
+//++
+// GetHandOffStatus
+//
+// This routine is called by all processors simultaneously, to get some hand-off
+// status that has been captured by IPF dispatcher and recorded in kernel registers.
+//
+// Arguments :
+//
+// On Entry : None.
+//
+// Return Value: Lid, R20Status.
+//
+//--
+//----------------------------------------------------------------------------------
+PROCEDURE_ENTRY (GetHandOffStatus)
+
+ NESTED_SETUP (0,2+0,0,0)
+
+ mov r8 = ar.k6 // Health Status (Self test params)
+ mov r9 = ar.k4 // LID bits
+ mov r10 = ar.k3;; // SAL_E entry state
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ mov r11 = ar.k7 // Return address to PAL
+ #else
+ mov r11 = ar.k1 // Return address to PAL
+ #endif
+
+ NESTED_RETURN
+PROCEDURE_EXIT (GetHandOffStatus)
+//----------------------------------------------------------------------------------
+
+
diff --git a/Core/CPU/IPF/PeCoffLoaderEx.c b/Core/CPU/IPF/PeCoffLoaderEx.c
new file mode 100644
index 0000000..60018ed
--- /dev/null
+++ b/Core/CPU/IPF/PeCoffLoaderEx.c
@@ -0,0 +1,268 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ Fixes Intel Itanium(TM) specific relocation types
+
+
+Revision History
+
+--*/
+
+#include "TianoCommon.h"
+#include "EfiImage.h"
+
+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
+ Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
+
+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
+ *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
+ ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
+
+#define IMM64_IMM7B_INST_WORD_X 3
+#define IMM64_IMM7B_SIZE_X 7
+#define IMM64_IMM7B_INST_WORD_POS_X 4
+#define IMM64_IMM7B_VAL_POS_X 0
+
+#define IMM64_IMM9D_INST_WORD_X 3
+#define IMM64_IMM9D_SIZE_X 9
+#define IMM64_IMM9D_INST_WORD_POS_X 18
+#define IMM64_IMM9D_VAL_POS_X 7
+
+#define IMM64_IMM5C_INST_WORD_X 3
+#define IMM64_IMM5C_SIZE_X 5
+#define IMM64_IMM5C_INST_WORD_POS_X 13
+#define IMM64_IMM5C_VAL_POS_X 16
+
+#define IMM64_IC_INST_WORD_X 3
+#define IMM64_IC_SIZE_X 1
+#define IMM64_IC_INST_WORD_POS_X 12
+#define IMM64_IC_VAL_POS_X 21
+
+#define IMM64_IMM41a_INST_WORD_X 1
+#define IMM64_IMM41a_SIZE_X 10
+#define IMM64_IMM41a_INST_WORD_POS_X 14
+#define IMM64_IMM41a_VAL_POS_X 22
+
+#define IMM64_IMM41b_INST_WORD_X 1
+#define IMM64_IMM41b_SIZE_X 8
+#define IMM64_IMM41b_INST_WORD_POS_X 24
+#define IMM64_IMM41b_VAL_POS_X 32
+
+#define IMM64_IMM41c_INST_WORD_X 2
+#define IMM64_IMM41c_SIZE_X 23
+#define IMM64_IMM41c_INST_WORD_POS_X 0
+#define IMM64_IMM41c_VAL_POS_X 40
+
+#define IMM64_SIGN_INST_WORD_X 3
+#define IMM64_SIGN_SIZE_X 1
+#define IMM64_SIGN_INST_WORD_POS_X 27
+#define IMM64_SIGN_VAL_POS_X 63
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
+{
+ UINT64 *F64;
+ UINT64 FixupVal;
+
+ switch ((*Reloc) >> 12) {
+
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:
+
+ //
+ // Align it to bundle address before fixing up the
+ // 64-bit immediate value of the movl instruction.
+ //
+
+ Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
+ FixupVal = (UINT64)0;
+
+ //
+ // Extract the lower 32 bits of IMM64 from bundle
+ //
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ //
+ // Update 64-bit address
+ //
+ FixupVal += Adjust;
+
+ //
+ // Insert IMM64 into bundle
+ //
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
+ IMM64_IMM41b_SIZE_X,
+ IMM64_IMM41b_INST_WORD_POS_X,
+ IMM64_IMM41b_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
+ IMM64_IMM41c_SIZE_X,
+ IMM64_IMM41c_INST_WORD_POS_X,
+ IMM64_IMM41c_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
+ IMM64_SIGN_SIZE_X,
+ IMM64_SIGN_INST_WORD_POS_X,
+ IMM64_SIGN_VAL_POS_X
+ );
+
+ F64 = (UINT64 *) Fixup;
+ if (*FixupData != NULL) {
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
+ *(UINT64 *)(*FixupData) = *F64;
+ *FixupData = *FixupData + sizeof(UINT64);
+ }
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
+ images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA64) || (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Core/CPU/IPF/PeCoffLoaderEx.h b/Core/CPU/IPF/PeCoffLoaderEx.h
new file mode 100644
index 0000000..fc14551
--- /dev/null
+++ b/Core/CPU/IPF/PeCoffLoaderEx.h
@@ -0,0 +1,87 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ Fixes Intel Itanium(TM) specific relocation types
+
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
+ images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IPF/PerformancePrimitives.s b/Core/CPU/IPF/PerformancePrimitives.s
new file mode 100644
index 0000000..5aeb886
--- /dev/null
+++ b/Core/CPU/IPF/PerformancePrimitives.s
@@ -0,0 +1,61 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// PerformancePrimitives.s
+//
+// Abstract:
+//
+//
+// Revision History:
+//
+//--
+
+.file "PerformancePrimitives.s"
+
+#include "IpfMacro.i"
+
+//-----------------------------------------------------------------------------
+//++
+// GetTimerValue
+//
+// Implementation of CPU-based time service
+//
+// On Entry :
+// EFI_STATUS
+// GetTimerValue (
+// OUT UINT64 *TimerValue
+// )
+//
+// Return Value:
+// r8 = Status
+// r9 = 0
+// r10 = 0
+// r11 = 0
+//
+// As per static calling conventions.
+//
+//--
+//---------------------------------------------------------------------------
+PROCEDURE_ENTRY (GetTimerValue)
+
+ NESTED_SETUP (1,8,0,0)
+ mov r8 = ar.itc;;
+ st8 [r32]= r8
+ mov r8 = r0
+ mov r9 = r0
+ mov r10 = r0
+ mov r11 = r0
+ NESTED_RETURN
+
+PROCEDURE_EXIT (GetTimerValue)
+//---------------------------------------------------------------------------
+
diff --git a/Core/CPU/IPF/Processor.h b/Core/CPU/IPF/Processor.h
new file mode 100644
index 0000000..8e49d37
--- /dev/null
+++ b/Core/CPU/IPF/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the Ipf processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE * 2)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE * 2)
+
+#endif \ No newline at end of file
diff --git a/Core/CPU/IPF/SwitchStack.s b/Core/CPU/IPF/SwitchStack.s
new file mode 100644
index 0000000..5de7e18
--- /dev/null
+++ b/Core/CPU/IPF/SwitchStack.s
@@ -0,0 +1,122 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// SwitchStack.s
+//
+// Abstract:
+//
+// Contains an implementation of a stack switch for the Itanium-based architecture.
+//
+//
+//
+// Revision History:
+//
+//--
+
+ .file "SwitchStack.s"
+
+#include <asm.h>
+#include <ia_64gen.h>
+
+// Define hardware RSE Configuration Register
+//
+// RS Configuration (RSC) bit field positions
+
+#define RSC_MODE 0
+#define RSC_PL 2
+#define RSC_BE 4
+// RSC bits 5-15 reserved
+#define RSC_MBZ0 5
+#define RSC_MBZ0_V 0x3ff
+#define RSC_LOADRS 16
+#define RSC_LOADRS_LEN 14
+// RSC bits 30-63 reserved
+#define RSC_MBZ1 30
+#define RSC_MBZ1_V 0x3ffffffffULL
+
+// RSC modes
+// Lazy
+#define RSC_MODE_LY (0x0)
+// Store intensive
+#define RSC_MODE_SI (0x1)
+// Load intensive
+#define RSC_MODE_LI (0x2)
+// Eager
+#define RSC_MODE_EA (0x3)
+
+// RSC Endian bit values
+#define RSC_BE_LITTLE 0
+#define RSC_BE_BIG 1
+
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+// RSE disabled: disabled, pl = 0, little endian, eager mode
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+
+
+//VOID
+//SwitchStacks (
+// VOID *ContinuationFunction,
+// UINTN Parameter,
+// UINTN NewTopOfStack,
+// UINTN NewBSPStore OPTIONAL
+//)
+///*++
+//
+//Input Arguments
+//
+// ContinuationFunction - This is a pointer to the PLABEL of the function that should be called once the
+// new stack has been created.
+// Parameter - The parameter to pass to the continuation function
+// NewTopOfStack - This is the new top of the memory stack for ensuing code. This is mandatory and
+// should be non-zero
+// NewBSPStore - This is the new BSP store for the ensuing code. It is optional on IA-32 and mandatory on Itanium-based platform.
+//
+//--*/
+
+PROCEDURE_ENTRY(SwitchStacks)
+
+ mov r16 = -0x10;;
+ and r16 = r34, r16;; // get new stack value in R16, 0 the last nibble.
+ mov r15 = r35;; // Get new BspStore into R15
+ mov r13 = r32;; // this is a pointer to the PLABEL of the continuation function.
+ mov r17 = r33;; // this is the parameter to pass to the continuation function
+
+ alloc r11=0,0,0,0 // Set 0-size frame
+ ;;
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED // for rse disable
+ ;;
+ mov ar.rsc = r21 // turn off RSE
+
+ add sp = r0, r16;; // transfer to the EFI stack
+ mov ar.bspstore = r15 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r18 = RSC_KERNEL_LAZ // RSC enabled, Lazy mode
+ ;;
+ mov ar.rsc = r18 // turn rse on, in kernel mode
+ ;;
+ alloc r11=0,0,1,0;; // alloc 0 outs going to ensuing DXE IPL service
+ mov out0 = r17
+ ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
+ ld8 gp = [r13] // gp = gp of continuation function from the PLABEL
+ mov b6 = r16
+ ;;
+ br.call.sptk.few b0=b6;; // Call the continuation function
+ ;;
+PROCEDURE_EXIT(SwitchStacks)
+
+
diff --git a/Core/CPU/IPF/SwitchToCacheMode.c b/Core/CPU/IPF/SwitchToCacheMode.c
new file mode 100644
index 0000000..9f938d4
--- /dev/null
+++ b/Core/CPU/IPF/SwitchToCacheMode.c
@@ -0,0 +1,77 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ SwitchToCacheMode.c
+
+Abstract:
+
+ Ipf CAR specific function used to switch to cache mode for the later memory access
+
+Revision History
+
+--*/
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "IpfCpuCore.i"
+
+extern
+SAL_RETURN_REGS
+GetHandOffStatus (
+ VOID
+ );
+
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+ )
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Phit;
+
+ if (CoreData == NULL) {
+ //
+ // the first call with CoreData as NULL.
+ //
+ return;
+ }
+
+ if ((GetHandOffStatus().r10 & 0xFF) == RecoveryFn) {
+ CoreData->StackBase = CoreData->StackBase & CACHE_MODE_ADDRESS_MASK;
+ CoreData->HobList.Raw = (UINT8 *)((UINTN)CoreData->HobList.Raw & CACHE_MODE_ADDRESS_MASK);
+
+ //
+ // Change the PHIT pointer value to cache mode
+ //
+ Phit = CoreData->HobList.HandoffInformationTable;
+
+ Phit->EfiMemoryTop = Phit->EfiMemoryTop & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiFreeMemoryTop = Phit->EfiFreeMemoryTop & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiMemoryBottom = Phit->EfiMemoryBottom & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiFreeMemoryBottom = Phit->EfiFreeMemoryBottom & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiEndOfHobList = Phit->EfiEndOfHobList & CACHE_MODE_ADDRESS_MASK;
+ }
+
+ return;
+} \ No newline at end of file
diff --git a/Core/CPU/IPF/asm.h b/Core/CPU/IPF/asm.h
new file mode 100644
index 0000000..2db93d6
--- /dev/null
+++ b/Core/CPU/IPF/asm.h
@@ -0,0 +1,35 @@
+//
+//
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// asm.h
+//
+// Abstract:
+//
+// This module contains generic macros for an assembly writer.
+//
+//
+// Revision History
+//
+#ifndef _ASM_H
+#define _ASM_H
+
+#define TRUE 1
+#define FALSE 0
+#define PROCEDURE_ENTRY(name) .##text; \
+ .##type name, @function; \
+ .##proc name; \
+ name::
+
+#define PROCEDURE_EXIT(name) .##endp name
+
+#endif // _ASM_H
diff --git a/Core/CPU/IPF/efijump.h b/Core/CPU/IPF/efijump.h
new file mode 100644
index 0000000..4a078ce
--- /dev/null
+++ b/Core/CPU/IPF/efijump.h
@@ -0,0 +1,112 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an IA32 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// NOTE:Set/LongJump needs to have this buffer start
+// at 16 byte boundary. Either fix the structure
+// which call this buffer or fix inside SetJump/LongJump
+// Choosing 1K buffer storage for now
+//
+typedef struct {
+ CHAR8 Buffer[1024];
+} EFI_JUMP_BUFFER;
+
+EFI_STATUS
+SetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ )
+/*++
+
+Routine Description:
+
+ SetJump stores the current register set in the area pointed to
+by "save". It returns zero. Subsequent calls to "LongJump" will
+restore the registers and return non-zero to the same location.
+ On entry, r32 contains the pointer to the jmp_buffer
+
+Arguments:
+
+ This - Calling context
+ Jump - Jump buffer
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+LongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ )
+/*++
+
+Routine Description:
+
+ LongJump initializes the register set to the values saved by a
+previous 'SetJump' and jumps to the return location saved by that
+'SetJump'. This has the effect of unwinding the stack and returning
+for a second time to the 'SetJump'.
+
+Arguments:
+
+ This - Calling context
+ Jump - Jump buffer
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+VOID
+RtPioICacheFlush (
+ IN VOID *StartAddress,
+ IN UINTN SizeInBytes
+ )
+/*++
+
+Routine Description:
+
+ Flushing the CPU instruction cache.
+
+Arguments:
+
+ StartAddress - Start address to flush
+ SizeInBytes - Length in bytes to flush
+
+Returns:
+
+ None
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IPF/ia_64gen.h b/Core/CPU/IPF/ia_64gen.h
new file mode 100644
index 0000000..8e8d1a5
--- /dev/null
+++ b/Core/CPU/IPF/ia_64gen.h
@@ -0,0 +1,214 @@
+//
+//
+//
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//Module Name: ia_64gen.h
+//
+//
+//Abstract:
+//
+//
+//
+//
+//Revision History
+//
+//
+#ifndef _IA64GEN_H
+#define _IA64GEN_H
+
+#define TT_UNAT 0
+#define C_PSR 0
+#define J_UNAT 0
+#define T_TYPE 0
+#define T_IPSR 0x8
+#define T_ISR 0x10
+#define T_IIP 0x18
+#define T_IFA 0x20
+#define T_IIPA 0x28
+#define T_IFS 0x30
+#define T_IIM 0x38
+#define T_RSC 0x40
+#define T_BSP 0x48
+#define T_BSPSTORE 0x50
+#define T_RNAT 0x58
+#define T_PFS 0x60
+#define T_KBSPSTORE 0x68
+#define T_UNAT 0x70
+#define T_CCV 0x78
+#define T_DCR 0x80
+#define T_PREDS 0x88
+#define T_NATS 0x90
+#define T_R1 0x98
+#define T_GP 0x98
+#define T_R2 0xa0
+#define T_R3 0xa8
+#define T_R4 0xb0
+#define T_R5 0xb8
+#define T_R6 0xc0
+#define T_R7 0xc8
+#define T_R8 0xd0
+#define T_R9 0xd8
+#define T_R10 0xe0
+#define T_R11 0xe8
+#define T_R12 0xf0
+#define T_SP 0xf0
+#define T_R13 0xf8
+#define T_R14 0x100
+#define T_R15 0x108
+#define T_R16 0x110
+#define T_R17 0x118
+#define T_R18 0x120
+#define T_R19 0x128
+#define T_R20 0x130
+#define T_R21 0x138
+#define T_R22 0x140
+#define T_R23 0x148
+#define T_R24 0x150
+#define T_R25 0x158
+#define T_R26 0x160
+#define T_R27 0x168
+#define T_R28 0x170
+#define T_R29 0x178
+#define T_R30 0x180
+#define T_R31 0x188
+#define T_F2 0x1f0
+#define T_F3 0x200
+#define T_F4 0x210
+#define T_F5 0x220
+#define T_F6 0x230
+#define T_F7 0x240
+#define T_F8 0x250
+#define T_F9 0x260
+#define T_F10 0x270
+#define T_F11 0x280
+#define T_F12 0x290
+#define T_F13 0x2a0
+#define T_F14 0x2b0
+#define T_F15 0x2c0
+#define T_F16 0x2d0
+#define T_F17 0x2e0
+#define T_F18 0x2f0
+#define T_F19 0x300
+#define T_F20 0x310
+#define T_F21 0x320
+#define T_F22 0x330
+#define T_F23 0x340
+#define T_F24 0x350
+#define T_F25 0x360
+#define T_F26 0x370
+#define T_F27 0x380
+#define T_F28 0x390
+#define T_F29 0x3a0
+#define T_F30 0x3b0
+#define T_F31 0x3c0
+#define T_FPSR 0x1e0
+#define T_B0 0x190
+#define T_B1 0x198
+#define T_B2 0x1a0
+#define T_B3 0x1a8
+#define T_B4 0x1b0
+#define T_B5 0x1b8
+#define T_B6 0x1c0
+#define T_B7 0x1c8
+#define T_EC 0x1d0
+#define T_LC 0x1d8
+#define J_NATS 0x8
+#define J_PFS 0x10
+#define J_BSP 0x18
+#define J_RNAT 0x20
+#define J_PREDS 0x28
+#define J_LC 0x30
+#define J_R4 0x38
+#define J_R5 0x40
+#define J_R6 0x48
+#define J_R7 0x50
+#define J_SP 0x58
+#define J_F2 0x60
+#define J_F3 0x70
+#define J_F4 0x80
+#define J_F5 0x90
+#define J_F16 0xa0
+#define J_F17 0xb0
+#define J_F18 0xc0
+#define J_F19 0xd0
+#define J_F20 0xe0
+#define J_F21 0xf0
+#define J_F22 0x100
+#define J_F23 0x110
+#define J_F24 0x120
+#define J_F25 0x130
+#define J_F26 0x140
+#define J_F27 0x150
+#define J_F28 0x160
+#define J_F29 0x170
+#define J_F30 0x180
+#define J_F31 0x190
+#define J_FPSR 0x1a0
+#define J_B0 0x1a8
+#define J_B1 0x1b0
+#define J_B2 0x1b8
+#define J_B3 0x1c0
+#define J_B4 0x1c8
+#define J_B5 0x1d0
+#define TRAP_FRAME_LENGTH 0x3d0
+#define C_UNAT 0x28
+#define C_NATS 0x30
+#define C_PFS 0x8
+#define C_BSPSTORE 0x10
+#define C_RNAT 0x18
+#define C_RSC 0x20
+#define C_PREDS 0x38
+#define C_LC 0x40
+#define C_DCR 0x48
+#define C_R1 0x50
+#define C_GP 0x50
+#define C_R4 0x58
+#define C_R5 0x60
+#define C_R6 0x68
+#define C_R7 0x70
+#define C_SP 0x78
+#define C_R13 0x80
+#define C_F2 0x90
+#define C_F3 0xa0
+#define C_F4 0xb0
+#define C_F5 0xc0
+#define C_F16 0xd0
+#define C_F17 0xe0
+#define C_F18 0xf0
+#define C_F19 0x100
+#define C_F20 0x110
+#define C_F21 0x120
+#define C_F22 0x130
+#define C_F23 0x140
+#define C_F24 0x150
+#define C_F25 0x160
+#define C_F26 0x170
+#define C_F27 0x180
+#define C_F28 0x190
+#define C_F29 0x1a0
+#define C_F30 0x1b0
+#define C_F31 0x1c0
+#define C_FPSR 0x1d0
+#define C_B0 0x1d8
+#define C_B1 0x1e0
+#define C_B2 0x1e8
+#define C_B3 0x1f0
+#define C_B4 0x1f8
+#define C_B5 0x200
+#define TT_R2 0x8
+#define TT_R3 0x10
+#define TT_R8 0x18
+#define TT_R9 0x20
+#define TT_R10 0x28
+#define TT_R11 0x30
+#define TT_R14 0x38
+
+#endif _IA64GEN_H
diff --git a/Core/CPU/IPF/pioflush.s b/Core/CPU/IPF/pioflush.s
new file mode 100644
index 0000000..0f0d760
--- /dev/null
+++ b/Core/CPU/IPF/pioflush.s
@@ -0,0 +1,106 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// pioflush.s
+//
+// Abstract:
+//
+//
+// Revision History:
+//
+//--
+
+ .file "pioflush.c"
+ .radix D
+ .section .text, "ax", "progbits"
+ .align 32
+ .section .pdata, "a", "progbits"
+ .align 4
+ .section .xdata, "a", "progbits"
+ .align 8
+ .section .data, "wa", "progbits"
+ .align 16
+ .section .rdata, "a", "progbits"
+ .align 16
+ .section .bss, "wa", "nobits"
+ .align 16
+ .section .tls$, "was", "progbits"
+ .align 16
+ .section .sdata, "was", "progbits"
+ .align 16
+ .section .sbss, "was", "nobits"
+ .align 16
+ .section .srdata, "as", "progbits"
+ .align 16
+ .section .rdata, "a", "progbits"
+ .align 16
+ .section .rtcode, "ax", "progbits"
+ .align 32
+ .type RtPioICacheFlush# ,@function
+ .global RtPioICacheFlush#
+// Function compile flags: /Ogsy
+ .section .rtcode
+
+// Begin code for function: RtPioICacheFlush:
+ .proc RtPioICacheFlush#
+ .align 32
+RtPioICacheFlush:
+// File e:\tmp\pioflush.c
+ { .mii //R-Addr: 0X00
+ alloc r3=2, 0, 0, 0 //11, 00000002H
+ cmp4.leu p0,p6=32, r33;; //15, 00000020H
+ (p6) mov r33=32;; //16, 00000020H
+ }
+ { .mii //R-Addr: 0X010
+ nop.m 0
+ zxt4 r29=r33;; //21
+ dep.z r30=r29, 0, 5;; //21, 00000005H
+ }
+ { .mii //R-Addr: 0X020
+ cmp4.eq p0,p7=r0, r30 //21
+ shr.u r28=r29, 5;; //19, 00000005H
+ (p7) adds r28=1, r28;; //22, 00000001H
+ }
+ { .mii //R-Addr: 0X030
+ nop.m 0
+ shl r27=r28, 5;; //25, 00000005H
+ zxt4 r26=r27;; //25
+ }
+ { .mfb //R-Addr: 0X040
+ add r31=r26, r32 //25
+ nop.f 0
+ nop.b 0
+ }
+$L143:
+ { .mii //R-Addr: 0X050
+ fc r32 //27
+ adds r32=32, r32;; //28, 00000020H
+ cmp.ltu p14,p15=r32, r31 //29
+ }
+ { .mfb //R-Addr: 0X060
+ nop.m 0
+ nop.f 0
+ (p14) br.cond.dptk.few $L143#;; //29, 880000/120000
+ }
+ { .mmi
+ sync.i;;
+ srlz.i
+ nop.i 0;;
+ }
+ { .mfb //R-Addr: 0X070
+ nop.m 0
+ nop.f 0
+ br.ret.sptk.few b0;; //31
+ }
+// End code for function:
+ .endp RtPioICacheFlush#
+// END
diff --git a/Core/CPU/IPF/processor.c b/Core/CPU/IPF/processor.c
new file mode 100644
index 0000000..9740948
--- /dev/null
+++ b/Core/CPU/IPF/processor.c
@@ -0,0 +1,118 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include "PeiHob.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+EFI_STATUS
+WinNtFlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ SetJump,
+ LongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ WinNtFlushInstructionCacheFlush
+};
+
+EFI_STATUS
+InstallEfiPeiTransferControl (
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WinNtFlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+
+Arguments:
+
+ This - Pointer to CPU Architectural Protocol interface
+ Start - Start adddress in memory to flush
+ Length - Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ RtPioICacheFlush ((UINT8 *) Start, (UINTN) Length);
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/IPF/setjmp.s b/Core/CPU/IPF/setjmp.s
new file mode 100644
index 0000000..ee27ca7
--- /dev/null
+++ b/Core/CPU/IPF/setjmp.s
@@ -0,0 +1,325 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// setjmp.s
+//
+// Abstract:
+//
+// Contains an implementation of setjmp and longjmp for the
+// Itanium-based architecture.
+//
+//
+//
+// Revision History:
+//
+//--
+
+ .file "setjmp.s"
+
+#include <asm.h>
+#include <ia_64gen.h>
+
+// int SetJump(struct jmp_buffer save)
+//
+// Setup a non-local goto.
+//
+// Description:
+//
+// SetJump stores the current register set in the area pointed to
+// by "save". It returns zero. Subsequent calls to "LongJump" will
+// restore the registers and return non-zero to the same location.
+//
+// On entry, r32 contains the pointer to the jmp_buffer
+//
+
+PROCEDURE_ENTRY(SetJump)
+ //
+ // Make sure buffer is aligned at 16byte boundary
+ //
+ mov r32 = r33
+
+ add r10 = -0x10,r0 ;; // mask the lower 4 bits
+ and r32 = r32, r10;;
+ add r32 = 0x10, r32;; // move to next 16 byte boundary
+
+ add r10 = J_PREDS, r32 // skip Unats & pfs save area
+ add r11 = J_BSP, r32
+ //
+ // save immediate context
+ //
+ mov r2 = ar.bsp // save backing store pointer
+ mov r3 = pr // save predicates
+ ;;
+ //
+ // save user Unat register
+ //
+ mov r16 = ar.lc // save loop count register
+ mov r14 = ar.unat // save user Unat register
+
+ st8 [r10] = r3, J_LC-J_PREDS
+ st8 [r11] = r2, J_R4-J_BSP
+ ;;
+ st8 [r10] = r16, J_R5-J_LC
+ st8 [r32] = r14, J_NATS // Note: Unat at the
+ // beginning of the save area
+ mov r15 = ar.pfs
+ ;;
+ //
+ // save preserved general registers & NaT's
+ //
+ st8.spill [r11] = r4, J_R6-J_R4
+ ;;
+ st8.spill [r10] = r5, J_R7-J_R5
+ ;;
+ st8.spill [r11] = r6, J_SP-J_R6
+ ;;
+ st8.spill [r10] = r7, J_F3-J_R7
+ ;;
+ st8.spill [r11] = sp, J_F2-J_SP
+ ;;
+ //
+ // save spilled Unat and pfs registers
+ //
+ mov r2 = ar.unat // save Unat register after spill
+ ;;
+ st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs
+ ;;
+ st8 [r32] = r15 // save pfs
+ //
+ // save floating registers
+ //
+ stf.spill [r11] = f2, J_F4-J_F2
+ stf.spill [r10] = f3, J_F5-J_F3
+ ;;
+ stf.spill [r11] = f4, J_F16-J_F4
+ stf.spill [r10] = f5, J_F17-J_F5
+ ;;
+ stf.spill [r11] = f16, J_F18-J_F16
+ stf.spill [r10] = f17, J_F19-J_F17
+ ;;
+ stf.spill [r11] = f18, J_F20-J_F18
+ stf.spill [r10] = f19, J_F21-J_F19
+ ;;
+ stf.spill [r11] = f20, J_F22-J_F20
+ stf.spill [r10] = f21, J_F23-J_F21
+ ;;
+ stf.spill [r11] = f22, J_F24-J_F22
+ stf.spill [r10] = f23, J_F25-J_F23
+ ;;
+ stf.spill [r11] = f24, J_F26-J_F24
+ stf.spill [r10] = f25, J_F27-J_F25
+ ;;
+ stf.spill [r11] = f26, J_F28-J_F26
+ stf.spill [r10] = f27, J_F29-J_F27
+ ;;
+ stf.spill [r11] = f28, J_F30-J_F28
+ stf.spill [r10] = f29, J_F31-J_F29
+ ;;
+ stf.spill [r11] = f30, J_FPSR-J_F30
+ stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr
+ //
+ // save FPSR register & branch registers
+ //
+ mov r2 = ar.fpsr // save fpsr register
+ mov r3 = b0
+ ;;
+ st8 [r11] = r2, J_B1-J_FPSR
+ st8 [r10] = r3, J_B2-J_B0
+ mov r2 = b1
+ mov r3 = b2
+ ;;
+ st8 [r11] = r2, J_B3-J_B1
+ st8 [r10] = r3, J_B4-J_B2
+ mov r2 = b3
+ mov r3 = b4
+ ;;
+ st8 [r11] = r2, J_B5-J_B3
+ st8 [r10] = r3
+ mov r2 = b5
+ ;;
+ st8 [r11] = r2
+ ;;
+ //
+ // return
+ //
+ mov r8 = r0 // return 0 from setjmp
+ mov ar.unat = r14 // restore unat
+ br.ret.sptk b0
+
+PROCEDURE_EXIT(SetJump)
+
+
+//
+// void LongJump(struct jmp_buffer *)
+//
+// Perform a non-local goto.
+//
+// Description:
+//
+// LongJump initializes the register set to the values saved by a
+// previous 'SetJump' and jumps to the return location saved by that
+// 'SetJump'. This has the effect of unwinding the stack and returning
+// for a second time to the 'SetJump'.
+//
+
+PROCEDURE_ENTRY(LongJump)
+ //
+ // Make sure buffer is aligned at 16byte boundary
+ //
+ mov r32 = r33
+
+ add r10 = -0x10,r0 ;; // mask the lower 4 bits
+ and r32 = r32, r10;;
+ add r32 = 0x10, r32;; // move to next 16 byte boundary
+
+ //
+ // caching the return value as we do invala in the end
+ //
+/// mov r8 = r33 // return value
+ mov r8 = 1 // For now return hard coded 1
+
+ //
+ // get immediate context
+ //
+ mov r14 = ar.rsc // get user RSC conf
+ add r10 = J_PFS, r32 // get address of pfs
+ add r11 = J_NATS, r32
+ ;;
+ ld8 r15 = [r10], J_BSP-J_PFS // get pfs
+ ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs
+ ;;
+ mov ar.unat = r2
+ ;;
+ ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer
+ mov ar.rsc = r0 // put RSE in enforced lazy
+ mov ar.pfs = r15
+ ;;
+
+ //
+ // while returning from longjmp the BSPSTORE and BSP needs to be
+ // same and discard all the registers allocated after we did
+ // setjmp. Also, we need to generate the RNAT register since we
+ // did not flushed the RSE on setjmp.
+ //
+ mov r17 = ar.bspstore // get current BSPSTORE
+ ;;
+ cmp.ltu p6,p7 = r17, r16 // is it less than BSP of
+(p6) br.spnt.few .flush_rse
+ mov r19 = ar.rnat // get current RNAT
+ ;;
+ loadrs // invalidate dirty regs
+ br.sptk.many .restore_rnat // restore RNAT
+
+.flush_rse:
+ flushrs
+ ;;
+ mov r19 = ar.rnat // get current RNAT
+ mov r17 = r16 // current BSPSTORE
+ ;;
+.restore_rnat:
+ //
+ // check if RNAT is saved between saved BSP and curr BSPSTORE
+ //
+ dep r18 = 1,r16,3,6 // get RNAT address
+ ;;
+ cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE
+ ;;
+(p8) ld8 r19 = [r18] // get RNAT from RSE
+ ;;
+ mov ar.bspstore = r16 // set new BSPSTORE
+ ;;
+ mov ar.rnat = r19 // restore RNAT
+ mov ar.rsc = r14 // restore RSC conf
+
+
+ ld8 r3 = [r11], J_R4-J_LC // get lc register
+ ld8 r2 = [r10], J_R5-J_PREDS // get predicates
+ ;;
+ mov pr = r2, -1
+ mov ar.lc = r3
+ //
+ // restore preserved general registers & NaT's
+ //
+ ld8.fill r4 = [r11], J_R6-J_R4
+ ;;
+ ld8.fill r5 = [r10], J_R7-J_R5
+ ld8.fill r6 = [r11], J_SP-J_R6
+ ;;
+ ld8.fill r7 = [r10], J_F2-J_R7
+ ld8.fill sp = [r11], J_F3-J_SP
+ ;;
+ //
+ // restore floating registers
+ //
+ ldf.fill f2 = [r10], J_F4-J_F2
+ ldf.fill f3 = [r11], J_F5-J_F3
+ ;;
+ ldf.fill f4 = [r10], J_F16-J_F4
+ ldf.fill f5 = [r11], J_F17-J_F5
+ ;;
+ ldf.fill f16 = [r10], J_F18-J_F16
+ ldf.fill f17 = [r11], J_F19-J_F17
+ ;;
+ ldf.fill f18 = [r10], J_F20-J_F18
+ ldf.fill f19 = [r11], J_F21-J_F19
+ ;;
+ ldf.fill f20 = [r10], J_F22-J_F20
+ ldf.fill f21 = [r11], J_F23-J_F21
+ ;;
+ ldf.fill f22 = [r10], J_F24-J_F22
+ ldf.fill f23 = [r11], J_F25-J_F23
+ ;;
+ ldf.fill f24 = [r10], J_F26-J_F24
+ ldf.fill f25 = [r11], J_F27-J_F25
+ ;;
+ ldf.fill f26 = [r10], J_F28-J_F26
+ ldf.fill f27 = [r11], J_F29-J_F27
+ ;;
+ ldf.fill f28 = [r10], J_F30-J_F28
+ ldf.fill f29 = [r11], J_F31-J_F29
+ ;;
+ ldf.fill f30 = [r10], J_FPSR-J_F30
+ ldf.fill f31 = [r11], J_B0-J_F31 ;;
+
+ //
+ // restore branch registers and fpsr
+ //
+ ld8 r16 = [r10], J_B1-J_FPSR // get fpsr
+ ld8 r17 = [r11], J_B2-J_B0 // get return pointer
+ ;;
+ mov ar.fpsr = r16
+ mov b0 = r17
+ ld8 r2 = [r10], J_B3-J_B1
+ ld8 r3 = [r11], J_B4-J_B2
+ ;;
+ mov b1 = r2
+ mov b2 = r3
+ ld8 r2 = [r10], J_B5-J_B3
+ ld8 r3 = [r11]
+ ;;
+ mov b3 = r2
+ mov b4 = r3
+ ld8 r2 = [r10]
+ ld8 r21 = [r32] // get user unat
+ ;;
+ mov b5 = r2
+ mov ar.unat = r21
+
+ //
+ // invalidate ALAT
+ //
+ invala ;;
+
+ br.ret.sptk b0
+PROCEDURE_EXIT(LongJump)
+
+
diff --git a/Core/CPU/MBIOSMAC.MAC b/Core/CPU/MBIOSMAC.MAC
new file mode 100644
index 0000000..5fe3105
--- /dev/null
+++ b/Core/CPU/MBIOSMAC.MAC
@@ -0,0 +1,512 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*****************************************************************;
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MBIOSMAC.MAC 1 2/07/12 3:58a Davidhsieh $
+;
+; $Revision: 1 $
+;
+; $Date: 2/07/12 3:58a $
+;*****************************************************************;
+;*****************************************************************;
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MBIOSMAC.MAC $
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;
+;*****************************************************************;
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: MBIOSMAC.MAC
+;
+; Description: Assembly Macros
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+
+ifndef _mbiosmac_mac_
+_mbiosmac_mac_ equ 1
+.xlist
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_NEAR
+;
+; Description: External Near macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_NEAR MACRO LabelName
+
+ EXTERN LabelName:NEAR ; Define the label as a NEAR EXTERN.
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_NEAR32
+;
+; Description: External Near 32 Macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_NEAR32 MACRO LabelName
+
+ EXTERN LabelName:NEAR32 ; Define the label as a NEAR EXTERN.
+
+ENDM
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_FAR
+;
+; Description: External Far macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_FAR MACRO LabelName
+
+ EXTERN LabelName:FAR ; Define the label as a FAR EXTERN.
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_NEAR
+;
+; Description: Start Near procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_NEAR MACRO LabelName
+
+LabelName PROC NEAR PUBLIC
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_NEAR32
+;
+; Description: Start Near 32-bit procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_NEAR32 MACRO LabelName
+
+LabelName PROC NEAR32 PUBLIC
+
+ENDM
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_CALL_PROC_NEAR
+;
+; Description: Call near macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_CALL_PROC_NEAR MACRO LabelID, LabelName
+
+ call LabelName
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_NEAR
+;
+; Description: Jump Near Macro. Provide a return label to jump to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_NEAR MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_NEAR32
+;
+; Description: Jump near 32-bit macro. Provide a return label to jump to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_NEAR32 MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_NEAR
+;
+; Description: End near procedure macro. Last in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_NEAR MACRO LabelName
+
+ ret
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_NEAR
+;
+; Description: End of procedure and jump near macro. Last procedure in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_NEAR MACRO LabelName
+
+ EXTERN LabelName&End:NEAR
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_NEAR32
+;
+; Description: Jump Near 32-bit macro. Last macro in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_NEAR32 MACRO LabelName
+
+ EXTERN LabelName&End:NEAR32
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_FAR
+;
+; Description: Far procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_FAR MACRO LabelName
+
+LabelName PROC FAR PUBLIC
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_CALL_PROC_FAR
+;
+; Description: Call far macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_CALL_PROC_FAR MACRO LabelID, LabelName
+
+ call LabelName
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_FAR
+;
+; Description: jmp far macro with return label to jump back to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_FAR MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_FAR
+;
+; Description: Ret procedure macro. Last in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_FAR MACRO LabelName
+
+ ret
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_FAR
+;
+; Description: End procedure macro. Last in agroup.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_FAR MACRO LabelName
+
+ EXTERN LabelName&End:FAR
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_TBL
+;
+; Description: Start table macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_TBL MACRO LabelName
+
+ PUBLIC LabelName
+LabelName LABEL BYTE
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_TBL_ENTRY_NEAR
+;
+; Description: Start table enty macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_TBL_ENTRY_NEAR MACRO LabelID, LabelName
+
+ stTblEntryNEAR <LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_ID_AND_TBL_ENTRY_NEAR
+;
+; Description: Start ID Table Entry macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_ID_AND_TBL_ENTRY_NEAR MACRO LabelID, LabelName
+
+ stIDAndTblEntryNEAR <LabelID, LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_TBL_ENTRY_FAR
+;
+; Description:
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_TBL_ENTRY_FAR MACRO LabelID, LabelName
+
+ stTblEntryFAR <LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_ID_AND_TBL_ENTRY_FAR
+;
+; Description:
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_ID_AND_TBL_ENTRY_FAR MACRO LabelID, LabelName
+
+ stIDAndTblEntryFAR <LabelID, LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_TBL
+;
+; Description:
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_TBL MACRO LabelName
+
+ PUBLIC LabelName&End
+LabelName&End LABEL BYTE
+
+ENDM
+
+.list
+
+endif ;_mbiosmac_mac_
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/FwhFvb.c b/Core/CPU/MicrocodeUpdate/FwhFvb.c
new file mode 100644
index 0000000..9450272
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/FwhFvb.c
@@ -0,0 +1,140 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/FwhFvb.c 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/FwhFvb.c $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FwhFvb.c
+//
+// Description:
+// This file contains code for flash update used by the MicrocodeUpdate module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#include "Flash.h"
+#include "Token.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FwhFvbErase
+//
+// Description: This function erases a block of NVRAM.
+//
+// Input: Address - Address of the block to erase
+//
+// Output: Return Status based on errors that occurred while erasing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FwhErase(
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN FlashBlockStart = BLOCK(Address);
+ UINTN FlashBlockEnd = BLOCK(Address + NumberOfBytes - 1);
+ UINTN FlashBlock;
+ BOOLEAN bStatus;
+
+ FlashDeviceWriteEnable();
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteEnable((UINT8*)FlashBlock);
+ bStatus = FlashEraseBlock((UINT8*)FlashBlock);
+ FlashBlockWriteDisable((UINT8*)FlashBlock);
+ if (!bStatus) break;
+ }
+
+ FlashDeviceWriteDisable();
+
+ return bStatus ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FwhWrite
+//
+// Description: This function writes a block of NVRAM.
+//
+// Input: Address - Address of the block to write.
+// Buffer - Pointer to a buffer containing data to write.
+// NumberOfBytes - The number of bytes to write
+//
+// Output: Return Status based on errors that occurred while writing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FwhWrite(
+ IN UINT8 *Buffer,
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+)
+{
+ BOOLEAN bStatus;
+ UINTN FlashBlockStart = BLOCK(Address);
+ UINTN FlashBlockEnd = BLOCK(Address + NumberOfBytes - 1);
+ UINTN FlashBlock;
+
+ FlashDeviceWriteEnable();
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteEnable((UINT8*)FlashBlock);
+ }
+
+
+ bStatus = FlashProgram((UINT8*)Address, Buffer, (UINT32)NumberOfBytes);
+
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteDisable((UINT8*)FlashBlock);
+ }
+
+ FlashDeviceWriteDisable();
+
+ return bStatus ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c
new file mode 100644
index 0000000..bc3b696
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c
@@ -0,0 +1,1164 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.c 4 4/14/15 2:48a Crystallee $
+//
+// $Revision: 4 $
+//
+// $Date: 4/14/15 2:48a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.c $
+//
+// 4 4/14/15 2:48a Crystallee
+//
+// 3 5/15/14 2:32a Crystallee
+// [TAG] EIP169079
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Microcode update
+// SWSMI.
+//
+// 2 10/28/12 11:23p Davidhsieh
+// [TAG] EIP104874
+// [Category] Improvement
+// [Description] Add signature check before search microcode ffs
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MicrocodeUpdate.c
+//
+// Description: Microcode Update SMI handler.
+// This file contains code for processing Interrupt 15 function
+// D042h, and for registering the callback that does the processing.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <token.h>
+#include <AmiDxeLib.h>
+#include <Ffs.h>
+#include <AmiCspLibInc.h>
+#include "MicrocodeUpdate.h"
+#include <AmiSmm.h>
+#include <AmiHobs.h>
+
+#ifndef INT15_D042_SWSMI
+#define INT15_D042_SWSMI 0x44
+#endif
+
+#pragma optimize("", off)
+
+EFI_GUID gMcodeFfsguid =
+ {0x17088572, 0x377F, 0x44ef, 0x8F,0x4E,0xB0,0x9F,0xFF,0x46,0xA0,0x70};
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+
+#if MICROCODE_SPLIT_BB_UPDATE
+UINT8 *gMcodeFlashStartFixed = 0;
+UINT32 gMcodeFlashSizeFixed = 0;
+#endif
+
+UINT8 *gMcodeFlashStartUpdate = 0;
+UINT32 gMcodeFlashSizeUpdate = 0;
+
+typedef enum {
+ MCODE_BLK_EMPTY = 0,
+ MCODE_BLK_START,
+ MCODE_BLK_CONT
+} MCODE_BLK_TYPE;
+
+typedef struct {
+ UINT8 *Addr;
+ UINT32 Size; //0 if less than 64k
+ MCODE_BLK_TYPE Type;
+} MCODE_BLK_MAP;
+
+UINT16 gNumMcodeBlks = 0;
+UINT16 gFirstEmptyBlk = 0xffff;
+MCODE_BLK_MAP *gMcodeBlkMap = NULL;
+
+UINT32 gCpuSignature;
+UINT8 gCpuFlag;
+UINT32 gUcRevision;
+
+SMM_HOB gSmmHob;
+
+#define MAX_MICROCODE_UPDATE_FUNCTIONS 4
+VOID(*MicrocodeUpdate[4])(SMI_UC_DWORD_REGS *) = {
+ PresenceTest, WriteUpdateData, UpdateControl, ReadUpdateData
+};
+
+#define MICROCODE_SIZE(Hdr) \
+ (((MICROCODE_HEADER*)(Hdr))->TotalSize ? ((MICROCODE_HEADER*)Hdr)->TotalSize : 2048)
+
+#if PACK_MICROCODE
+#define MICROCODE_ALIGN_SIZE(Hdr) \
+ ((MICROCODE_SIZE(Hdr) + 16 - 1) & ~(16 - 1))
+#else
+#define MICROCODE_ALIGN_SIZE(Hdr) \
+ ((MICROCODE_SIZE(Hdr) + MICROCODE_BLOCK_SIZE - 1) & ~(MICROCODE_BLOCK_SIZE - 1))
+#endif
+
+#if PACK_MICROCODE
+#define MICROCODE_BLOCKS(Hdr) \
+ ((((MICROCODE_SIZE(Hdr) + MICROCODE_BLOCK_SIZE - 1) & ~(MICROCODE_BLOCK_SIZE - 1)))/MICROCODE_BLOCK_SIZE)
+#else
+ #define MICROCODE_BLOCKS(Hdr) (MICROCODE_ALIGN_SIZE(Hdr)/MICROCODE_BLOCK_SIZE)
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckAddressRange
+//
+// Description: Check address range to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Range - length of the area
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// EFI_ACCESS_DENIED - Access denied!
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range )
+{
+ // Check the size and range
+ if ( ((EFI_PHYSICAL_ADDRESS)Address >= gSmmHob.Tseg) &&
+ ((EFI_PHYSICAL_ADDRESS)Address <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ if ( (((EFI_PHYSICAL_ADDRESS)Address + Range) >= gSmmHob.Tseg) &&
+ (((EFI_PHYSICAL_ADDRESS)Address + Range) <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsValidHeader
+//
+// Description: Check if the header is valid.
+//
+// Input: MICROCODE_HEADER *uHeader -- Address of Microcode Header.
+//
+// Output: BOOLEAN -- TRUE if microcode header is valid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsValidHeader(MICROCODE_HEADER *uHeader)
+{
+ if (uHeader->HeaderVersion != UC_HEADER_VERSION) return FALSE;
+ if (uHeader->LoaderRevison != UC_LOADER_REVISION) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsValidChecksum
+//
+// Description: Validate the checksum.
+//
+// Input:
+// VOID *Microcode - Address of Microcode Header.
+// UINT32 Size - Microcode Size.
+//
+// Output: BOOLEAN -- TRUE if checksum is valid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsValidChecksum(VOID *Mcode, UINT32 Size)
+{
+ UINT32 NumDwords = Size >> 2;
+ UINT32 *p32 = (UINT32*)Mcode;
+ UINT32 Checksum = 0;
+ UINT32 i;
+
+ for(i = 0; i < NumDwords; ++i) Checksum += p32[i]; //Checksum is the summation dwords.
+
+ return Checksum == 0 ? TRUE : FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInstalledMicrocodeRevision
+//
+// Description: Get the installed microcode revision on the cpu.
+//
+// Input: VOID
+//
+// Output: UINT32 - Revision of microcode currently installed on CPU.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetInstalledMicrocodeRevision()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ //Clear IA32_BIOS_SIGN_ID of microcode loaded.
+ WriteMsr(0x8b, 0); //IA32_BIOS_SIGN_ID
+
+ //Reading CPU ID 1, updates the MSR to the microcode revision.
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ return (UINT32) Shr64(ReadMsr(0x8b), 32);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CountBlks
+//
+// Description: Count blocks taken by microcode in FFS.
+//
+// Input:
+// IN UINT8 *McodeStart - Start of microcode in FFS.
+// IN UINT32 McodeSize - Size of microcode and empty space in FFS.
+// IN BOOLEAN CountEmpty - TRUE if calculate blocks for empty space.
+//
+// Output: UINT16 - Number of blocks needed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CountBlks(IN UINT8 *McodeStart, IN UINT32 McodeSize, IN BOOLEAN CountEmpty)
+{
+ UINT8 *p = McodeStart;
+ UINT8 *EndOfMcode = p + McodeSize;
+ UINT16 TotBlks = 0;
+
+ while(p < EndOfMcode) {
+ if (*(UINT32*)p != 0xffffffff && *(UINT32*)p != 0) {
+ TotBlks += MICROCODE_BLOCKS(p);
+ p += MICROCODE_ALIGN_SIZE(p);
+ } else if (CountEmpty) {
+ TotBlks += (UINT16)((EndOfMcode - p) / MICROCODE_BLOCK_SIZE);
+ break;
+ }
+ else break;
+ }
+
+ return TotBlks;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillMicrocodeBlkMap
+//
+// Description: Update gMcodeBlkMap with data for microcode.
+//
+// Input:
+// IN OUT *BlkStart - On Input: Start update with this block. Output: Next call use this value.
+// IN UINT8 *McodeStart - Start of microcode in FFS.
+// IN UINT32 McodeSize - Size of microcode and empty space in FFS.
+// IN BOOLEAN CountEmpty - TRUE if update blocks for empty space.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillMicrocodeBlkMap(IN OUT UINT16 *BlkStart, IN UINT8 *McodeStart, IN UINT32 McodeSize, IN BOOLEAN CountEmpty)
+{
+ UINT8 *p = McodeStart;
+ UINT8 *EndOfMcode = p + McodeSize;
+ UINT16 BlkIndex = *BlkStart;
+
+ while(p < EndOfMcode) {
+ if (*(UINT32*)p != 0xffffffff && *(UINT32*)p != 0) {
+ UINT16 NumBlks = MICROCODE_BLOCKS(p);
+ UINT32 McodeSize = MICROCODE_SIZE(p);
+#if PACK_MICROCODE == 0
+ UINT32 PackDiff = MICROCODE_ALIGN_SIZE(p) - McodeSize;
+#endif
+
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_START;
+ if (NumBlks <= 1 && McodeSize < MICROCODE_BLOCK_SIZE) {
+ gMcodeBlkMap[BlkIndex].Size = McodeSize;
+ }
+ p += gMcodeBlkMap[BlkIndex].Size;
+ McodeSize -= gMcodeBlkMap[BlkIndex].Size;
+ ++BlkIndex;
+ while(--NumBlks) {
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_CONT;
+ if (NumBlks == 1 && McodeSize < MICROCODE_BLOCK_SIZE) {
+ gMcodeBlkMap[BlkIndex].Size = McodeSize;
+ }
+ p += gMcodeBlkMap[BlkIndex].Size;
+ McodeSize -= gMcodeBlkMap[BlkIndex].Size;
+ ++BlkIndex;
+ }
+#if PACK_MICROCODE == 0
+ p += PackDiff;
+#endif
+ } else if (CountEmpty) {
+ gFirstEmptyBlk = BlkIndex;
+ while (BlkIndex < gNumMcodeBlks) {
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_EMPTY;
+ BlkIndex++;
+ }
+ break;
+ } else break;
+ }
+ *BlkStart = BlkIndex;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitMcodeBlkMap
+//
+// Description: Initialize gMcodeBlkMap and related globals for all microcode FFS.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitMcodeBlkMap()
+{
+ UINT16 BlkStart = 0;
+
+ if (gMcodeBlkMap != NULL) pSmst->SmmFreePool(gMcodeBlkMap);
+ gNumMcodeBlks = 0;
+#if MICROCODE_SPLIT_BB_UPDATE
+ gNumMcodeBlks += CountBlks(gMcodeFlashStartFixed, gMcodeFlashSizeFixed, FALSE);
+#endif
+ gNumMcodeBlks += CountBlks(gMcodeFlashStartUpdate, gMcodeFlashSizeUpdate, TRUE);
+
+ pSmst->SmmAllocatePool(0, gNumMcodeBlks * sizeof(MCODE_BLK_MAP), &gMcodeBlkMap);
+
+ gFirstEmptyBlk = 0xffff;
+#if MICROCODE_SPLIT_BB_UPDATE
+ FillMicrocodeBlkMap(&BlkStart, gMcodeFlashStartFixed, gMcodeFlashSizeFixed, FALSE);
+#endif
+ FillMicrocodeBlkMap(&BlkStart, gMcodeFlashStartUpdate, gMcodeFlashSizeUpdate, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindMicrocodeFfs
+//
+// Description: Find Micorode FFS in FV.
+//
+// Input: IN EFI_FIRMWARE_VOLUME_HEADER *FvHdr - Firmware volume to search
+//
+// Output: UINT8 * - Return FFS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 *FindMicrocodeFfs(IN EFI_FIRMWARE_VOLUME_HEADER *FvHdr)
+{
+ UINT8 *FvPtr = (UINT8*)FvHdr + FvHdr->HeaderLength;
+ UINT8 *EndOfFv = (UINT8*)FvHdr + FvHdr->FvLength;
+
+ //Check for corrupt firmware volume.
+ if (FvHdr->Signature != 'HVF_') return NULL;
+ //Search the FV_MAIN firmware volume for the microcode file.
+ while (FvPtr < EndOfFv && *FvPtr != -1) {
+ if (guidcmp(&gMcodeFfsguid, &((EFI_FFS_FILE_HEADER*)FvPtr)->Name)==0)
+ return FvPtr;
+
+ FvPtr += *(UINT32*)&((EFI_FFS_FILE_HEADER*)FvPtr)->Size & 0xffffff;
+ FvPtr = (UINT8*)(((UINTN)FvPtr + 7) & ~7); //8 byte alignment
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitMicrocodeVariables
+//
+// Description: Initialize global variables used by the driver.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN InitMicrocodeVariables()
+{
+ UINT8 *FfsPtr;
+ UINT32 McodeFfsSize;
+ UINT64 MsrValue;
+ UINT32 RegEbx, RegEcx, RegEdx;
+#if MICROCODE_SPLIT_BB_UPDATE
+ UINT16 MPDTLengthFixed;
+#endif
+ UINT16 MPDTLengthUpdate;
+
+#if MICROCODE_SPLIT_BB_UPDATE
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_BASE);
+ if (FfsPtr == NULL) return FALSE;
+
+ gMcodeFlashStartFixed = FfsPtr + sizeof(EFI_FFS_FILE_HEADER);
+ McodeFfsSize = ((*(UINT32*)((EFI_FFS_FILE_HEADER*)FfsPtr)->Size) & 0xffffff);
+#if MPDTable_CREATED
+ MPDTLengthFixed = *(UINT16*)(FfsPtr + McodeFfsSize - 2); //Last 2 bytes is table size.
+#else
+ MPDTLengthFixed = 0;
+#endif
+ gMcodeFlashSizeFixed = McodeFfsSize - sizeof(EFI_FFS_FILE_HEADER) - MPDTLengthFixed;
+#endif
+
+#if MICROCODE_SPLIT_BB_UPDATE
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_UPDATE_BASE);
+#else
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_BASE);
+#endif
+ if (FfsPtr == NULL) return FALSE;
+
+ gMcodeFlashStartUpdate = FfsPtr + sizeof(EFI_FFS_FILE_HEADER);
+ McodeFfsSize = ((*(UINT32*)((EFI_FFS_FILE_HEADER*)FfsPtr)->Size) & 0xffffff);
+#if MPDTable_CREATED
+ MPDTLengthUpdate = *(UINT16*)(FfsPtr + McodeFfsSize - 2); //Last 2 bytes is table size.
+#else
+ MPDTLengthUpdate = 0;
+#endif
+ gMcodeFlashSizeUpdate = McodeFfsSize - sizeof(EFI_FFS_FILE_HEADER) - MPDTLengthUpdate;
+
+ InitMcodeBlkMap();
+
+ //Clear revision value. CPUID of 1 will update this revision value.
+ WriteMsr(0x8b, 0); //IA32_BIOS_SIGN_ID
+
+ CPULib_CpuID(1, &gCpuSignature, &RegEbx, &RegEcx, &RegEdx);
+ gCpuSignature &= 0x00ffffff;
+ MsrValue = ReadMsr(0x17);
+ gCpuFlag = (UINT8)(Shr64(MsrValue, 50) & 7); //Get the CPU flags.
+ gUcRevision = (UINT32) Shr64(ReadMsr(0x8b), 32); //Get the current microcode revision loaded.
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindMicrocodeOfStepping
+//
+// Description: Search the microcode in the firmware for the cpu signature
+// or earlier steping.
+//
+// Input:
+// UINT8 *Mcode - Address of Mcode Header.
+// UINT8 *End - Mcode End.
+// UINT32 CpuSignature - Signature of CPU to find.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *FindMicrocodeOfStepping(UINT8 *Mcode, UINT8 *End, UINT32 CpuSignature)
+{
+ UINT8 *ptr;
+ for(ptr = Mcode; ptr < End; ptr += MICROCODE_ALIGN_SIZE(ptr)) {
+ MICROCODE_HEADER* uC = (MICROCODE_HEADER*)ptr;
+
+ if (*(UINT32*)ptr == 0xffffffff || *(UINT32*)ptr == 0) return 0;
+ if (uC->CpuSignature == CpuSignature) return ptr;
+
+ if (uC->TotalSize > (uC->DataSize + 48)) { //Extended signature count.
+ MICROCODE_EXT_PROC_SIG_TABLE *SigTable = (MICROCODE_EXT_PROC_SIG_TABLE*)(ptr + uC->DataSize + 48);
+ UINT32 ExtSigCount = SigTable->Count;
+ UINT8 i;
+
+ for (i = 0; i < ExtSigCount; ++i) {
+ if (SigTable->ProcSig[i].CpuSignature == CpuSignature) return ptr;
+ }
+ }
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadMicrocode
+//
+// Description: Load the microcode onto the CPU.
+//
+// Input:
+// VOID *Mcode - Address of Microcode Header.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LoadMicrocode(IN VOID *Mcode)
+{
+ WriteMsr(0x79, (UINT64)(UINTN)Mcode + 48); //IA32_BIOS_UPDT_TRIG
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadMicrocodeEachCpu
+//
+// Description: Load the microcode on each CPU.
+//
+// Input: EFI_SMI_CPU_SAVE_STATE *CpuSaveState
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LoadMicrocodeEachCpu(IN VOID *Mcode)
+{
+ UINT8 i;
+ //In for loop, BSP CPU will return error and continue for all APs.
+ for (i = 0; i < pSmst->NumberOfCpus; ++i) {
+ pSmst->SmmStartupThisAp(LoadMicrocode, i, Mcode);
+ }
+ LoadMicrocode(Mcode);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PresenceTest
+//
+// Description: Execute the presence test function for int 15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+//
+// Input:
+// AX - D042h
+// BL - 00h i.e., PRESCENCE_TEST
+//
+// Output:
+// CF NC - All return values are valid
+// CY - Failure, AH contains status.
+//
+// AH Return code
+// AL Additional OEM information
+// EBX Part one of the signature 'INTE'.
+// ECX Part two of the signature 'LPEP'.
+// EDX Version number of the BIOS update loader
+// SI Number of update blocks system can record in NVRAM (1 based).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PresenceTest(SMI_UC_DWORD_REGS *Regs)
+{
+ Regs->EBX = 'INTE'; //Part 1 of the Signature
+ Regs->ECX = 'LPEP'; //Part 2 of the Signature.
+ Regs->EDX = UC_LOADER_VERSION;
+
+ *(UINT16*)&Regs->ESI = gNumMcodeBlks; //Number of blocks.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateControl
+//
+// Description: Execute the update control for int 15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+// Input:
+// AX - D042h
+// BL - 02h i.e., UPDATE_CONTROL
+// BH - Task
+// 1 - Enable the update loading at initialization time.
+// 2 - Determine the current state of the update control without changing its status.
+//
+// Output:
+// AH Return code
+// AL Additional OEM information
+// BL Update status Disable or Enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UpdateControl(SMI_UC_DWORD_REGS *Regs)
+{
+
+ //This is checking for a task of 0 or > 2. This is not in the specification, but in Intel code.
+ if ((Regs->EBX & 0xff00) == 0 || (Regs->EBX & 0x0ff00) > 0x200) { //Check BH
+ // Indicate we cannot determinate the Enable/Disable status via CMOS
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_READ_FAILURE;
+ }
+
+ Regs->EBX = (Regs->EBX & 0xffffff00) | UC_INT15_ENABLE; // Always enabled.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadUpdateData
+//
+// Description: Read microcode using int15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+//
+// Input:
+// AX - D042h
+// BL - 03h i.e., READ_UPDATE_DATA
+// ES:DI - Real Mode Pointer to the Intel Update structure.
+// SS:SP - Stack pointer (32K minimum)
+// SI - Update number, the index number of the update block to be read.
+// This number is zero based and must be less than the update
+// count returned from the prescence test function.
+//
+// Output:
+// AH Return code
+// AL Additional OEM information
+// BL Update status Disable or Enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ReadUpdateData(SMI_UC_DWORD_REGS *Regs)
+{
+ EFI_STATUS Status;
+ UINT16 Index = (UINT16)Regs->ESI;
+ UINT8 *UpdateBuffer;
+ MICROCODE_HEADER *Header;
+
+ if (Index >= gNumMcodeBlks) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_UPDATE_NUM_INVALID;
+ return;
+ }
+
+ if (gMcodeBlkMap[Index].Type == MCODE_BLK_CONT) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_EMPTY;
+ return;
+ }
+
+ UpdateBuffer = (UINT8*)(UINTN)(((UINT16)Regs->ES << 4) + (UINT16)Regs->EDI);
+
+ Status = CheckAddressRange (UpdateBuffer, MICROCODE_BLOCK_SIZE);
+ if(EFI_ERROR(Status)) return;
+
+ if (gMcodeBlkMap[Index].Type == MCODE_BLK_EMPTY) {
+ MemSet(UpdateBuffer, MICROCODE_BLOCK_SIZE, 0xff);
+ return;
+ }
+
+ Header = (MICROCODE_HEADER *)gMcodeBlkMap[Index].Addr;
+
+ MemCpy(UpdateBuffer, Header, MICROCODE_SIZE(Header));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+
+static UINT8 *gFlashBlk; //Pointer to current flash block to write.
+static UINT8 *gFlashBuffer; //Pointer to beginning of buffer.
+static UINT8 *gFlashBufferPos; //Pointer to current posisiton.
+static UINT32 gFlashBufferUsed; //Number of bytes used in the buffer.
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlushBufferToFlash
+//
+// Description: Helper function to write the buffer to the flash and reset the buffer.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FlushBufferToFlash()
+{
+ FwhErase((UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ FwhWrite(gFlashBuffer, (UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ gFlashBlk += FLASH_BLOCK_SIZE;
+ gFlashBufferPos = gFlashBuffer;
+ gFlashBufferUsed = 0;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeFlashBuffer
+//
+// Description: Initialize the flash buffer before using.
+//
+// Input:
+// IN UINT8* FirstFlashBlk - Address of first block to flash.
+// IN UINT8* FlashBuffer - Flash Buffer.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeFlashBuffer(IN UINT8* FirstFlashBlk, IN UINT8 *FlashBuffer)
+{
+ gFlashBlk = FirstFlashBlk;
+ gFlashBuffer = FlashBuffer;
+ gFlashBufferPos = gFlashBuffer;
+ gFlashBufferUsed = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyToFlashBuffer
+//
+// Description: Copy data to the buffer. When the buffer is full, write to the flash,
+// and continues to copy data.
+//
+// Input:
+// IN UINT8 Data - Start of data to write.
+// IN UINT32 Size - Amount to Write.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CopyToFlashBuffer(IN UINT8 *Data, IN UINT32 Size)
+{
+ while (Size) {
+ if (gFlashBufferUsed + Size <= FLASH_BLOCK_SIZE) {
+ MemCpy(gFlashBufferPos, Data, Size);
+
+ gFlashBufferPos += Size;
+ gFlashBufferUsed += Size;
+
+ if (gFlashBufferUsed == FLASH_BLOCK_SIZE) FlushBufferToFlash();
+ return;
+ }
+
+ MemCpy(gFlashBufferPos, Data, FLASH_BLOCK_SIZE - gFlashBufferUsed);
+ Data += FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ Size -= FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ FlushBufferToFlash();
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteValueToFlashBuffer
+//
+// Description: Fill part of the buffer with a value. When the buffer is full, write to the flash,
+// and continue to update the beginning of the buffer with a value.
+//
+// Input:
+// IN UINT8 Value - Value to write.
+// IN UINT32 Size - Amount to Write.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteValueToFlashBuffer(IN UINT8 Value, IN UINT32 Size)
+{
+
+ while (Size) {
+ if (gFlashBufferUsed + Size <= FLASH_BLOCK_SIZE) {
+ MemSet(gFlashBufferPos, Size, Value);
+
+ gFlashBufferPos += Size;
+ gFlashBufferUsed += Size;
+
+ if (gFlashBufferUsed == FLASH_BLOCK_SIZE) FlushBufferToFlash();
+ return;
+ }
+
+ MemSet(gFlashBufferPos, FLASH_BLOCK_SIZE - gFlashBufferUsed, Value);
+ Size -= FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ FlushBufferToFlash();
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillBufferAndFlush
+//
+// Description: Fill the rest of the buffer of a size of the flash block, then update the flash.
+//
+// Input: IN UINT8 *Data - Pointer to starting of data to write to the flash.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillFlashBufferAndFlush(IN UINT8 *Data)
+{
+ if (gFlashBufferUsed != 0) {
+ MemCpy(gFlashBufferPos, Data, FLASH_BLOCK_SIZE - gFlashBufferUsed);
+ FwhErase((UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ FwhWrite(gFlashBuffer, (UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMI_UC_DWORD_REGS
+//
+// Description: Write microcode to flash and load microcode into each CPU.
+//
+// Input: EFI_SMI_CPU_SAVE_STATE *Regs
+//
+// Output: VOID
+//
+// Input:
+// AX - D042h
+// BL - 01h i.e., WRITE_UPDATE_DATA
+// ES:DI - Real Mode Pointer to the Intel Update structure.
+// CX - Scratch Pad1 (Real Mode Scratch segment 64K in length)
+// DX - Scratch Pad2 (Real Mode Scratch segment 64K in length)
+// SI - Scratch Pad3 (Real Mode Scratch segment 64K in length)
+// SS:SP - Stack pointer (32K minimum)
+//
+// Output:
+// CF NC - All return values are valid
+// CY - Failure, AH contains status.
+//
+// AH Return code
+// AL Additional OEM information
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteUpdateData(SMI_UC_DWORD_REGS *Regs)
+{
+ EFI_STATUS Status;
+ UINT8 *NewMcode = (UINT8*)(UINTN)((Regs->ES << 4) + (Regs->EDI & 0xFFFF));
+ MICROCODE_HEADER *Header = (MICROCODE_HEADER*)NewMcode;
+ INT32 NewMcodeAlignSize = MICROCODE_ALIGN_SIZE(NewMcode);
+ INT32 NewMcodeSize = MICROCODE_SIZE(NewMcode);
+ BOOLEAN Compact = FALSE;
+
+ UINT8 *OldMcode;
+ INT32 OldMcodeAlignSize;
+ UINT8 *BlkStart;
+ UINT8 *McodeUpdateStart;
+ UINT8 *Buffer;
+
+ Status = CheckAddressRange(NewMcode, NewMcodeAlignSize);
+ if(EFI_ERROR(Status)) return;
+
+ if (!IsValidHeader(Header)) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_HEADER;
+ return;
+ }
+
+ if (!IsValidChecksum(NewMcode, NewMcodeSize)) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_HEADER_CS;
+ return;
+ }
+
+ //Only update if microcode is for the installed CPU.
+ if (Header->CpuSignature != gCpuSignature || !(Header->Flags & (1<<gCpuFlag))) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_CPU_NOT_PRESENT;
+ return;
+ }
+
+ //Only update a different revision.
+ if (Header->UpdateRevision == gUcRevision) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_REVISION;
+ return;
+ }
+
+ //If no microcode installed, then the revision is 0.
+ if (gUcRevision != 0) { //Quick check.
+ if(FindMicrocodeOfStepping(gMcodeFlashStartUpdate,
+ gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate,
+ gCpuSignature
+ ) != NULL) {
+ Compact = TRUE; //Remove old version.
+ }
+ }
+ if (gFirstEmptyBlk == 0xffff || NewMcodeAlignSize >
+ (gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate - gMcodeBlkMap[gFirstEmptyBlk].Addr)
+ ) Compact = TRUE; //Volume is full.
+
+ if (!Compact) {
+ //Append blocks.
+ UINT8 *pEmptyBlk = gMcodeBlkMap[gFirstEmptyBlk].Addr;
+ LoadMicrocodeEachCpu(NewMcode); //Install new microcode.
+
+ //Check to see if new microcode is installed.
+ if (Header->UpdateRevision != GetInstalledMicrocodeRevision()) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_SECURITY_FAILURE;
+ return;
+ }
+
+ FwhWrite(NewMcode, (UINTN)pEmptyBlk, NewMcodeSize); //Currently ignoring status
+
+ InitMcodeBlkMap();
+ return;
+ }
+
+ //***Compact Flash Part***
+
+ //Currently restrict FLASH_BLOCK_SIZE to 64k or smaller
+ if (FLASH_BLOCK_SIZE > 64 * 1024) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_IMPLEMENTED;
+ }
+
+ //Set up Buffer.
+ Buffer = (UINT8*)(UINTN)((UINT16)Regs->ECX << 4);
+
+ Status = CheckAddressRange(Buffer, FLASH_BLOCK_SIZE);
+ if(EFI_ERROR(Status)) return;
+
+ //Find existing microcode of same revision.
+ McodeUpdateStart = gFirstEmptyBlk == 0xffff ?
+ gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate : gMcodeBlkMap[gFirstEmptyBlk].Addr;
+
+ OldMcode = FindMicrocodeOfStepping(
+ gMcodeFlashStartUpdate,
+ McodeUpdateStart,
+ gCpuSignature
+ );
+
+ //Old Microcode not available to remove?
+ if (!OldMcode) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_STORAGE_FULL;
+ return;
+ }
+ OldMcodeAlignSize = MICROCODE_ALIGN_SIZE(OldMcode);;
+
+ //Check to see if space big enough for new microcode.
+ if ((gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate - McodeUpdateStart + OldMcodeAlignSize) < NewMcodeAlignSize) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_STORAGE_FULL;
+ return;
+ }
+
+ //Load new microcode, if can't load exit.
+ LoadMicrocodeEachCpu(NewMcode); //Install new microcode.
+ if (Header->UpdateRevision != GetInstalledMicrocodeRevision()) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_SECURITY_FAILURE;
+ return;
+ }
+
+ //Start compacting at block with Old Microcode to remove.
+ BlkStart = (UINT8*)((UINTN)OldMcode & ~(FLASH_BLOCK_SIZE - 1)); //Must start at block boundary.
+
+ //Note: When Buffer is full, it will flush to flash.
+ InitializeFlashBuffer(BlkStart, Buffer);
+ CopyToFlashBuffer(BlkStart, (UINT32)(OldMcode - BlkStart)); //Copy before old microcode.
+
+ CopyToFlashBuffer(OldMcode + OldMcodeAlignSize, (UINT32)(McodeUpdateStart - (OldMcode + OldMcodeAlignSize))); //Copy after old microcode.
+
+ CopyToFlashBuffer(NewMcode, NewMcodeSize); //Copy new microcode.
+
+ WriteValueToFlashBuffer(0xff, NewMcodeAlignSize - NewMcodeSize); //Fill block space after microcode.
+
+ if (NewMcodeAlignSize < OldMcodeAlignSize) {
+ WriteValueToFlashBuffer(0xff, OldMcodeAlignSize - NewMcodeAlignSize); //Write 0xff over reclaimed space. Polarity?
+ } else {
+ McodeUpdateStart += NewMcodeAlignSize - OldMcodeAlignSize;
+ }
+ FillFlashBufferAndFlush(McodeUpdateStart);
+
+ InitMcodeBlkMap();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MicrocodeUpdateCallback
+//
+// Description: This notification function is called when an SMM Mode
+// is invoked through SMI. This may happen during RT,
+// so it must be RT safe.
+// Interrupt 15h, function D042h is processed here.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output: Status code returned to function D042h caller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID MicrocodeUpdateCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ EFI_STATUS Status;
+ SMI_UC_DWORD_REGS *Regs;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1;
+ UINT8 Function;
+ UINTN i;
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+ Regs = (SMI_UC_DWORD_REGS*)(UINTN)(pSmst->CpuSaveState[Cpu].Ia32SaveState.ESI);
+
+ Status = CheckAddressRange((UINT8*)Regs, sizeof(SMI_UC_DWORD_REGS));
+ if(EFI_ERROR(Status)) return;
+
+ if ((UINT16)Regs->EAX != 0xD042) return;
+
+ Function = (UINT8)Regs->EBX; //BL
+
+ //Initialize return as successful.
+ Regs->EFLAGS &= ~CARRY_FLAG;
+ Regs->EAX &= 0xffff0000;
+
+ if (Function >= MAX_MICROCODE_UPDATE_FUNCTIONS) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_IMPLEMENTED;
+ return;
+ }
+
+ MicrocodeUpdate[Function](Regs);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: This function is called from the InitSmmHandler if driver is in SMM.
+//
+// Input: ImageHandle - Pointer to the loaded image protocol for this driver
+// SystemTable - Pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ SMM_HOB *SmmHob;
+ EFI_GUID SmmHobGuid = SMM_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ BOOLEAN IsInit = InitMicrocodeVariables();
+ if (!IsInit) return EFI_UNSUPPORTED;
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+ SmmHob = (SMM_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (SmmHob == NULL) return EFI_NOT_FOUND;
+
+ Status = FindNextHobByGuid(&SmmHobGuid,(VOID**)&SmmHob);
+ if (EFI_ERROR(Status)) return Status;
+
+ gSmmHob = *SmmHob;
+
+ SwContext.SwSmiInputValue = INT15_D042_SWSMI;
+
+ Status = pSwDispatch->Register(pSwDispatch, MicrocodeUpdateCallback, &SwContext, &Handle);
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeMicrocodeSmm
+//
+// Description: This function registers the INT15 D042 SW SMI handler
+// This is the driver entry pOoint.
+//
+// Input: ImageHandle - Pointer to the loaded image protocol for this driver
+// SystemTable - Pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitializeMicrocodeSmm(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif
new file mode 100644
index 0000000..8a965ea
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "MicrocodeUpdate"
+ category = ModulePart
+ LocalRoot = "Core\CPU\MicrocodeUpdate\"
+ RefName = "MicrocodeUpdate"
+[files]
+"MicrocodeUpdate.sdl"
+"MicrocodeUpdate.mak"
+"MicrocodeUpdate.c"
+"MicrocodeUpdate.h"
+"MicrocodeUpdate.dxs"
+"FwhFvb.c"
+<endComponent>
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs
new file mode 100644
index 0000000..f6a5ffa
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs
@@ -0,0 +1,48 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.dxs 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.dxs $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//**********************************************************************
+
+#include <Protocol\SmmSwDispatch.h>
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h
new file mode 100644
index 0000000..73b5dea
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h
@@ -0,0 +1,133 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.h 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.h $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MicrocodeUpdate.h
+//
+// Description: Header file for Microcode Update SMI handler.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _MICROCODE_UPDATE_H_
+#define _MICROCODE_UPDATE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define SIG_PART_ONE 0x0494e5445 // 'INTE'
+//#define SIG_PART_TWO 0x04c504550 // 'LPEP'
+
+
+#define CARRY_FLAG 1
+
+#define UC_LOADER_VERSION 1
+
+#define UC_HEADER_VERSION 1
+#define UC_LOADER_REVISION 1
+
+#define UC_INT15_ENABLE 0x01
+
+#define UC_PRESCENCE_TEST 0
+#define UC_WRITE_UPDATE_DATA 1
+#define UC_UPDATE_CONTROL 2
+#define UC_READ_UPDATE_DATA 3
+
+#define UC_SUCCESS 0x0000
+#define UC_NOT_IMPLEMENTED 0x8600
+#define UC_ERASE_FAILURE 0x9000
+#define UC_WRITE_FAILURE 0x9100
+#define UC_READ_FAILURE 0x9200
+#define UC_STORAGE_FULL 0x9300
+#define UC_CPU_NOT_PRESENT 0x9400
+#define UC_INVALID_HEADER 0x9500
+#define UC_INVALID_HEADER_CS 0x9600
+#define UC_SECURITY_FAILURE 0x9700
+#define UC_INVALID_REVISION 0x9800
+#define UC_UPDATE_NUM_INVALID 0x9900
+#define UC_NOT_EMPTY 0x9a00
+
+typedef struct {
+ UINT32 EAX;
+ UINT32 EBX;
+ UINT32 ECX;
+ UINT32 EDX;
+ UINT32 ESI;
+ UINT32 EDI;
+ UINT32 EFLAGS;
+ UINT16 ES;
+ UINT16 CS;
+ UINT16 SS;
+ UINT16 DS;
+ UINT16 FS;
+ UINT16 GS;
+ UINT32 EBP;
+} SMI_UC_DWORD_REGS;
+
+VOID PresenceTest(SMI_UC_DWORD_REGS *Regs);
+VOID WriteUpdateData(SMI_UC_DWORD_REGS *Regs);
+VOID UpdateControl(SMI_UC_DWORD_REGS *Regs);
+VOID ReadUpdateData(SMI_UC_DWORD_REGS *Regs);
+
+EFI_STATUS FwhErase(
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+);
+
+EFI_STATUS FwhWrite(
+ IN UINT8 *Buffer,
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+);
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak
new file mode 100644
index 0000000..160baf9
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak
@@ -0,0 +1,58 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.mak 1 2/07/12 3:59a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 2/07/12 3:59a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.mak $
+#
+# 1 2/07/12 3:59a Davidhsieh
+#
+#************************************************************************//
+
+all : MicrocodeUpdate
+
+MicrocodeUpdate: $(BUILD_DIR)\MicrocodeUpdate.mak MicrocodeUpdateBin
+
+$(BUILD_DIR)\MicrocodeUpdate.mak : $(MICROCODEUPDATE_PATH)\MicrocodeUpdate.cif $(MICROCODEUPDATE_PATH)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MICROCODEUPDATE_PATH)\MicrocodeUpdate.cif $(CIF2MAK_DEFAULTS)
+
+MicrocodeUpdateBin : $(AMIDXELIB) $(FLASHLIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MicrocodeUpdate.mak all\
+ GUID=F3331DE6-4A55-44e4-B767-7453F7A1A021\
+ ENTRY_POINT=InitializeMicrocodeSmm\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl
new file mode 100644
index 0000000..2acaf0d
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "MicrocodeUpdate_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Microcode Update support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+ Token = "Microcode_SUPPORT" "=" "1"
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "MICROCODEUPDATE_PATH"
+End
+
+MODULE
+ Help = "Includes MicorcodeUpdate.mak to Project"
+ File = "MicrocodeUpdate.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MicrocodeUpdate.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = " "
+ Parent = "$(BUILD_DIR)\MicrocodeUpdate.ffs"
+ Token = "AMI_DEBUGGER_SUPPORT" "=" "1"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/CPU/ResetVector.asm b/Core/CPU/ResetVector.asm
new file mode 100644
index 0000000..dd134ad
--- /dev/null
+++ b/Core/CPU/ResetVector.asm
@@ -0,0 +1,99 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/ResetVector.asm 3 6/15/12 3:27a Davidhsieh $
+;
+; $Revision: 3 $
+;
+; $Date: 6/15/12 3:27a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/ResetVector.asm $
+;
+; 3 6/15/12 3:27a Davidhsieh
+; [TAG] None
+; [Category] New Feature
+; [Description] For FIT module support
+;
+; 2 3/16/12 3:11a Davidhsieh
+; Setup items create for CPU RC policy
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: ResetVector.asm
+;
+; Description:
+; Reset Vector. Fixup will update code to jump to EntryPoint of Startup32.asm.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+.586P
+.XMM
+.model tiny
+
+include token.equ
+
+RESET_SEG SEGMENT PARA PUBLIC 'CODE' USE16
+ org 0 ;offset 0xFFFFFFC0h
+ifndef MKF_INTEL_FIT_TABLE_ADDRESS
+ dd 0EEEEEEEEh
+ dd 0EEEEEEEEh
+else
+ dd MKF_INTEL_FIT_TABLE_ADDRESS ;Reserve
+ dd 0h
+endif
+ org 10h ;offset 0xFFFFFFD0h
+ mov di, "AP" ;Actual AP startup (SIPI) is hardcoded to jump here.
+ jmp ApStartup
+
+ org 20h ;offset 0xFFFFFFE0
+ dd 87654321h ;Fixed up by tool to point to PEI CORE Entry.
+
+ org 30h ;offset 0xFFFFFFF0
+ nop ;Place holder to maintain byte sequence for build tool fix-ups.
+ nop ;Place holder to maintain byte sequence for build tool fix-ups.
+ApStartup:
+ ; Use machine code directly in case of the assembler optimization
+ ; SEC entry point relatvie address will be fixed up by some build tool.
+ ;
+ db 0e9h ;jmp Rel16
+ dw -3 ;SecFixup utility changes to point to flat32.asm Entry Point.
+
+ org 3ch ;offset 0xFFFFFFFC
+ dd 012345678h ;Fixed up by GenFvImage to Boot Firmware Volume Base.
+RESET_SEG ENDS
+END
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
diff --git a/Core/CPU/SecFixup.exe b/Core/CPU/SecFixup.exe
new file mode 100644
index 0000000..950343c
--- /dev/null
+++ b/Core/CPU/SecFixup.exe
Binary files differ
diff --git a/Core/CPU/Startup32.asm b/Core/CPU/Startup32.asm
new file mode 100644
index 0000000..9728a39
--- /dev/null
+++ b/Core/CPU/Startup32.asm
@@ -0,0 +1,618 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/Startup32.asm 3 11/28/12 1:11a Davidhsieh $
+;
+; $Revision: 3 $
+;
+; $Date: 11/28/12 1:11a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/Startup32.asm $
+;
+; 3 11/28/12 1:11a Davidhsieh
+; [TAG] EIP107763
+; [Category] Bug Fix
+; [Severity] Important
+; [Symptom] UEFI SCT 2.3.1 Floating Point ABI Test fail
+; [RootCause] According to UEFI 2.3.1 errata C, Floating-point control
+; word must be initialized to 0x037F
+; [Solution] Use 0x37f for Floating-point control word
+;
+; 2 3/09/12 2:13a Davidhsieh
+; Create BIST data
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: StartUp32.asm
+;
+; Description: Switch CPU to protected mode, INIT CAR and setup stack.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+.586P
+.XMM
+.model small
+
+include token.equ
+include cpu.equ
+
+ifndef MKF_PI_SPECIFICATION_VERSION
+MKF_PI_SPECIFICATION_VERSION EQU 0
+endif
+
+ifndef MKF_CSM_SUPPORT
+MKF_CSM_SUPPORT EQU 0
+endif
+
+ifndef MKF_MPDTable_CREATED
+MKF_MPDTable_CREATED EQU 0
+endif
+
+ifndef MKF_PACK_MICROCODE
+MKF_PACK_MICROCODE EQU 0
+endif
+
+ifndef MKF_MICROCODE_SPLIT_BB_UPDATE
+MKF_MICROCODE_SPLIT_BB_UPDATE EQU 0
+endif
+
+PhysMask equ (NOT (MKF_CAR_TOTAL_SIZE - 1)) ;8k stack
+
+WriteBack equ 6
+ValidMask equ 1 SHL 11
+
+IA32_MISC_ENABLE EQU 1A0h
+FAST_STRING_ENABLE_BIT EQU 01h
+
+MTRR_PHYS_BASE_0 EQU 0200h
+MTRR_PHYS_MASK_0 EQU 0201h
+MTRR_PHYS_BASE_1 EQU 0202h
+MTRR_PHYS_MASK_1 EQU 0203h
+MTRR_PHYS_BASE_2 EQU 0204h
+MTRR_PHYS_MASK_2 EQU 0205h
+MTRR_PHYS_BASE_3 EQU 0206h
+MTRR_PHYS_MASK_3 EQU 0207h
+MTRR_PHYS_BASE_4 EQU 0208h
+MTRR_PHYS_MASK_4 EQU 0209h
+MTRR_PHYS_BASE_5 EQU 020Ah
+MTRR_PHYS_MASK_5 EQU 020Bh
+MTRR_PHYS_BASE_6 EQU 020Ch
+MTRR_PHYS_MASK_6 EQU 020Dh
+MTRR_PHYS_BASE_7 EQU 020Eh
+MTRR_PHYS_MASK_7 EQU 020Fh
+MTRR_FIX_64K_00000 EQU 0250h
+MTRR_FIX_16K_80000 EQU 0258h
+MTRR_FIX_16K_A0000 EQU 0259h
+MTRR_FIX_4K_C0000 EQU 0268h
+MTRR_FIX_4K_C8000 EQU 0269h
+MTRR_FIX_4K_D0000 EQU 026Ah
+MTRR_FIX_4K_D8000 EQU 026Bh
+MTRR_FIX_4K_E0000 EQU 026Ch
+MTRR_FIX_4K_E8000 EQU 026Dh
+MTRR_FIX_4K_F0000 EQU 026Eh
+MTRR_FIX_4K_F8000 EQU 026Fh
+MTRR_DEF_TYPE EQU 02FFh
+
+EFI_PEI_PPI_DESCRIPTOR_PPI EQU 00000010h
+EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST EQU 80000000h
+
+FV_LENGTH EQU (16 + 16)
+FV_SIGNATURE EQU (FV_LENGTH + 8)
+FV_HDR_LENGTH EQU (FV_SIGNATURE + 4 + 4)
+
+FFS_LENGTH EQU (16 + 2 + 1 + 1)
+FFS_HDR_LENGTH EQU (FFS_LENGTH + 3 + 1)
+
+uCODE_CPU_SIGNATURE EQU 12
+uCODE_CPU_FLAGS EQU 24
+uCODE_DATA_SIZE EQU 28
+uCODE_TOTAL_SIZE EQU 32
+
+; Externs
+EXTERN SECCoreAtPowerOn:NEAR32
+PUBLIC SECCoreAtPowerOnEnd
+
+;STARTUP_SEG SEGMENT USE32
+;----------------------------------------------------------------------------
+; STARTUP_SEG S E G M E N T STARTS
+;----------------------------------------------------------------------------
+STARTUP_SEG SEGMENT PARA PUBLIC 'CODE' USE32
+
+MICOCODE_FFS_GUID label dword
+ dd 17088572h
+ dw 377Fh
+ dw 44efh
+ db 8Fh,4Eh,0B0h,9Fh,0FFh,46h,0A0h,70h
+
+AMI_BIST_GUID label dword
+ dd 0A7E2CE72h
+ dw 0DC32h
+ dw 04BC0h
+ db 9Eh, 35h, 0FEh, 0B3h, 0Ah, 0E5h, 0CCh, 47h
+
+SEC_CORE_PPI_DESC STRUCT
+ BIST_FLAGS dd ?
+ BIST_GUID dd ?
+ BIST_PPI dd ?
+SEC_CORE_PPI_DESC ends
+
+
+SecCorePpiDesc SEC_CORE_PPI_DESC < \
+ EFI_PEI_PPI_DESCRIPTOR_PPI + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \
+ offset AMI_BIST_GUID, \
+ 0 \
+>
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+; Procedure: FindMicrocode
+;
+; Description: This routine searches the file volume for a microcode update
+; and returns the address if found.
+;
+; Input: None
+;
+; Output: eax = Pointer to microcode. 0 if not found.
+;
+; Notes:
+; This routine can not use stack. It can be called from rom or ram.
+; If called from rom, a hard coded stack must be exist in rom.
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+IF MKF_Microcode_SUPPORT
+public FindMicrocode
+extern FindMicrocodeEnd:NEAR32
+FindMicrocode proc
+IF MKF_MICROCODE_SPLIT_BB_UPDATE
+ mov ebx, MKF_FV_MICROCODE_UPDATE_BASE
+FindMicrocodeFv:
+ELSE
+ mov ebx, MKF_FV_MICROCODE_BASE
+ENDIF
+ cmp dword ptr [ebx + FV_SIGNATURE], 'HVF_'
+ jne Microcode_Not_Found ;Corrupt FV?
+
+ mov edx, ebx
+ mov eax, [ebx + FV_HDR_LENGTH]
+ and eax, 0ffffh ;Get 16 bit FV header length
+ add ebx, eax ;ebx = start of FFS
+ jc Microcode_Not_Found ;Corrupt FV?
+ add edx, [edx + FV_LENGTH]
+ jz @f ;zf if Boot Block
+ jc Microcode_Not_Found ;Corrupt FV?
+@@:
+ dec edx ;edx = End of FFS
+;---Find File ---
+;ebx = Start of FFS
+;edx = End of FFS
+Get_Next_File:
+ cmp dword ptr [ebx], -1 ;Is in end of files, but not firmware volume.
+ je File_not_found
+ mov ecx, 4
+ mov esi, ebx
+ mov edi, offset MICOCODE_FFS_GUID
+ ;compare file guid
+ repe cmpsd
+ je Found_File
+;---get next file--
+ ;get file length and add to ebx
+ mov eax, [ebx + FFS_LENGTH]
+ and eax, 0ffffffh ;eax = File length (24 bits)
+ add ebx, eax ;next file
+ ;align file
+ add ebx, 7
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+ and ebx, not 7
+
+ cmp ebx, edx ;Is end of firmware volume?
+ jb Get_Next_file
+File_not_found:
+ jmp Microcode_Not_Found
+;---Found File---
+Found_File:
+;ebx = Start of Microcode FFS
+;edx = End of FFS + 1
+
+;---Search micocode for match.---
+ mov edi, ebx
+
+ mov eax, [ebx + FFS_LENGTH]
+ and eax, 0ffffffh ;eax = File length (24 bits)
+ add edi, eax ;edi = end of file
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+
+IF MKF_MPDTable_CREATED
+ movzx eax, word ptr [edi-2] ;eax = MPDT length
+ sub edi, eax ;edi = end of microcodes.
+ENDIF
+
+ add ebx, FFS_HDR_LENGTH
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+
+ mov esi, ebx
+
+ mov eax, 1
+ cpuid
+ mov ebx, eax ;ebx = CPU signature
+
+ mov ecx, 17h
+ rdmsr ;read CPUS flags
+
+ shr edx, 18
+ and dl, 7 ;dl = CPU FLAG
+ mov cl, dl
+ mov dl, 1
+ shl dl, cl ;dl = bit set for CPU flag
+
+ xchg ebx, esi ;ebx = ptr, esi = signature
+Next_Microcode:
+ cmp ebx, edi ;Check to see if microcode at end of FFS File.
+ jae Microcode_Not_Found
+
+ cmp dword ptr [ebx], 1 ;Check if correct header revision
+ jne Microcode_Not_Found
+
+ mov ecx, 2048 ;total size if data size in field = 0.
+ cmp dword ptr [ebx + uCODE_DATA_SIZE], 0
+ jz @f
+ mov ecx, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+@@:
+
+ cmp esi, [ebx + uCODE_CPU_SIGNATURE]
+ jne Check_Ext_Sig
+
+ mov eax, ebx ;Store uC addr in eax, so if jnz succeeds.
+ test dl, [ebx + uCODE_CPU_FLAGS] ;uC flags match?
+ jnz Exit_Find_Microcode
+
+Check_Ext_Sig:
+ mov ebp, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+ mov eax, [ebx + uCODE_DATA_SIZE] ;Get Data Size
+ add eax, 48
+ cmp ebp, eax
+ jbe Find_Next_Microcode ;No extended signature.
+
+ mov ecx, [ebx + eax] ;Get extended signature.
+ cmp ecx, 20
+ jae Microcode_Not_Found ;Corrupt?
+ lea ebp, [ebx + eax + 20] ;First Proc Signature.
+
+@@:
+ cmp [ebp], esi ;Check Signature
+ jne Next_Ext_Sig
+
+ mov eax, ebx
+ test dl, [ebp + 4] ;Check processor flags
+ jnz Exit_Find_Microcode
+Next_Ext_Sig:
+ add ebp, 12
+ loop @b
+ mov ecx, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+Find_Next_Microcode:
+ ;align to next block size
+IF MKF_PACK_MICROCODE
+ add ecx, 15
+ and ecx, 0fffffff0h
+ELSE
+ add ecx, MKF_MICROCODE_BLOCK_SIZE - 1
+ and ecx, NOT (MKF_MICROCODE_BLOCK_SIZE - 1)
+ENDIF
+ add ebx, ecx
+ jc Microcode_Not_Found ;Overflow - bad data.
+ jmp Next_Microcode
+
+Microcode_Not_Found:
+IF MKF_MICROCODE_SPLIT_BB_UPDATE
+ cmp ebx, MKF_FV_MICROCODE_BASE
+ jae @f
+ mov ebx, MKF_FV_MICROCODE_BASE
+ jmp FindMicrocodeFv
+@@:
+ENDIF
+ xor eax, eax
+Exit_Find_Microcode:
+ jmp FindMicrocodeEnd
+FindMicrocode endp
+
+ENDIF ;MKF_Microcode_SUPPORT
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: CPU_START
+;
+; Description: Switch CPU to protected mode, INIT CAR and setup stack.
+;
+; Input: None
+;
+; Output: None
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+public _CPU_START
+_CPU_START:
+ ;---16 bit in 32 bit assembler--
+ ;---Some 16-bit and 32-bit assmebly is the same, others are not.---
+ ;---Need to use some machine code.---
+
+ fninit ;Clear any pending Floating point exceptions
+ movd mm0, eax ;Save BIST state in MM0
+
+ cli
+
+if MKF_CSM_SUPPORT EQ -1
+ db 0B8h, 00h, 0F0h ;mov ax, 0F000h
+ db 8Eh, 0D8h ;mov ds, ax
+ db 0BEh, 0F0h, 0FFh ;mov si, 0FFF0h
+ db 80h, 3Ch, 0EAh ;cmp BYTE PTR [si], 0EAh ; Is it warm reset ?
+ jne NotWarmReset ; If not.
+
+ db 0EAh ;DB 0EAh ; Far jump to F000:E05B (legacy BIOS warm reset entry)
+ dw 0E05Bh ;DW 0E05Bh
+ dw 0F000h ;DW 0F000h
+NotWarmReset:
+endif
+
+ ;Switch to protected mode
+ ;lgdt fword ptr cs:[GdtDescriptor] ;Relative to 4G.
+; db 66h,2eh,0fh,1,16h
+; dw offset GdtDescriptor ;<-------Problem------<
+
+ db 66h
+ mov ebx, offset GdtDescriptor
+ ;lgdt fword ptr cs:[bx]
+ db 66h, 2eh,0fh,1,17h
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;In 16 bit protected mode
+
+ cld
+ db 0b8h ;mov ax, DATA_SEL
+ dw DATA_SEL
+ db 8eh, 0d8h ;mov ds, ax
+ db 8eh, 0c0h ;mov es, ax
+ db 8eh, 0d0h ;mov ss, ax
+ db 8eh, 0e0h ;mov fs, ax
+ db 8eh, 0e8h ;mov gs, ax
+
+ ;set cs segment
+ ;jmp 10:CHANGE_CS
+ db 66h, 0eah
+ dd CHANGE_CS ;Relative to 4G.
+ dw CODE_SEL
+CHANGE_CS:
+ ;---If Limit CPU ID enabled because of soft reset, disable.
+ mov ecx, 01a0h
+ rdmsr
+ btr eax, 22 ;Reset bit
+ jnc @f ;If already reset, don't write to 1a0.
+ wrmsr
+@@:
+ ;---Change APIC Address---
+ mov ecx, MSR_XAPIC_BASE ; Enable local APIC
+ rdmsr
+ and edx, NOT 0fh ;Mask local APIC address
+ and eax, NOT 0fffff000h ;Mask local APIC address
+ or eax, MKF_LOCAL_APIC_BASE
+ wrmsr
+
+;--------------------------------------------------------------------
+
+ ;In CR4, set OSFXSR bit 9 and OSXMMEXCPT bit 10
+ mov eax, cr4
+ or ax, 1 SHL 9 + 1 SHL 10
+ mov cr4, eax
+
+;---------------------------------------------
+;---------------------------------------------
+;---------------------------------------------
+
+; Invoke the SECCore Init hook for other components to hook functions
+; This also executes referece code.
+ jmp SECCoreAtPowerOn
+SECCoreAtPowerOnEnd::
+
+ ; This stores the BIST for SBSP.
+ ; The PBSPs BIST is stored in MM0. The value will preserved across INIT-SIPI and captured
+ ; in CPU PEI.
+ movd eax, mm0
+ pushd eax ;Bist0
+
+ ;Get Apic ID
+ mov eax, MKF_LOCAL_APIC_BASE + 20h
+ mov ebx, [eax]
+ shr ebx, 24
+ pushd ebx ;ApicId0
+ pushd 1 ;Num BISTS
+
+ mov ebx, esp ;points to AMI_BIST_PPI_STRUCT
+
+ sub esp, size SEC_CORE_PPI_DESC
+ mov esi, offset SecCorePpiDesc
+ mov edi, esp
+ mov ecx, size SEC_CORE_PPI_DESC / 4
+ rep movsd
+
+ mov (SEC_CORE_PPI_DESC PTR [esp]).BIST_PPI, ebx
+ mov ebx, esp
+
+IFDEF EFIx64
+ pushd 37fh
+ELSE
+ pushd 27fh
+ENDIF
+ fldcw word ptr [esp] ;Set FP control word according UEFI
+ add esp, 4
+
+ ; Pass NEM address into the PEI Core
+ push MKF_CAR_BASE_ADDRESS
+
+ ; Dispatch table
+ push ebx
+
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ ; Initialize EFI_SEC_PEI_HAND_OFF data structure in CAR
+ mov ebx, MKF_CAR_BASE_ADDRESS
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).DataSize, sizeof EFI_SEC_PEI_HAND_OFF
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).Reserved1, 0
+
+ ; Report the Boot Firmware Volume that PEI should search for PEIMS (FV_BB)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).BootFirmwareVolumeBase, MKF_FV_BB_BASE
+
+ ; Report the Size of the Boot Firmware Volume, in Bytes
+ mov eax, MKF_FV_BB_BASE + 32
+ mov eax, [eax]
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).BootFirmwareVolumeSize, eax
+
+ ; Report the start the CAR Base address and size (based on SDL tokens)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).TemporaryRamBase, MKF_CAR_BASE_ADDRESS
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).TemporaryRamSize, MKF_CAR_TOTAL_SIZE
+
+ ; Report the starting address of the CAR that PEI Core can use
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).PeiTemporaryRamBase, MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).PeiTemporaryRamSize, MKF_CAR_TOTAL_SIZE - sizeof EFI_SEC_PEI_HAND_OFF - EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+
+ ; Report the start of the stack and its size (should point into top of CAR region)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).StackBase, MKF_CAR_BASE_ADDRESS + MKF_CAR_TOTAL_SIZE
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).StackSize, MKF_CAR_TOTAL_SIZE
+
+ ; In CAR, reserve 8 bytes space before IDT Base Address for a pointer to a pointer
+ ; of the PEI Services Table (EFI_PEI_SERVICES**) which will be initialized in PEI
+
+ ; IDT Base Address = MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ ; IDT Size is 0 because it will be initalized in PEI. Here, it is only
+ ; used to reserved 8 bytes space for (EFI_PEI_SERVICES**)
+ sub esp, sizeof IDTR32
+ mov (IDTR32 ptr [esp]).BaseAddress, MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ mov (IDTR32 ptr [esp]).Limit, 0
+ lidt FWORD PTR [esp]
+ add esp, sizeof IDTR32
+
+ ; Push a pointer to the the EFI_PEI_PPI_DESCRIPTOR AMI_PI_TODO:
+ ;push 0
+
+ ; Push a pointer to the EFI_SEC_PEI_HAND_OFF data structure onto the stack
+ push MKF_CAR_BASE_ADDRESS
+
+ELSE
+ ; Pass stack size into the PEI Core
+ push MKF_CAR_TOTAL_SIZE
+
+ ; Pass BFV into the PEI Core
+ push DWORD PTR ds:[0FFFFFFFCh]
+ENDIF
+
+ ;mov edi, 0FFFFFFE0h
+ call DWORD PTR ds:[0FFFFFFE0h]
+;---Does not return---
+
+align 16
+MTRR_TABLE label byte
+ dw MTRR_DEF_TYPE
+ dw MTRR_PHYS_BASE_0, MTRR_PHYS_MASK_0
+ dw MTRR_PHYS_BASE_1, MTRR_PHYS_MASK_1
+ dw MTRR_PHYS_BASE_2, MTRR_PHYS_MASK_2
+ dw MTRR_PHYS_BASE_3, MTRR_PHYS_MASK_3
+ dw MTRR_PHYS_BASE_4, MTRR_PHYS_MASK_4
+ dw MTRR_PHYS_BASE_5, MTRR_PHYS_MASK_5
+ dw MTRR_PHYS_BASE_6, MTRR_PHYS_MASK_6
+ dw MTRR_PHYS_BASE_7, MTRR_PHYS_MASK_7
+ dw MTRR_FIX_64K_00000
+ dw MTRR_FIX_16K_80000
+ dw MTRR_FIX_16K_A0000
+ dw MTRR_FIX_4K_C0000, MTRR_FIX_4K_C8000
+ dw MTRR_FIX_4K_D0000, MTRR_FIX_4K_D8000
+ dw MTRR_FIX_4K_E0000, MTRR_FIX_4K_E8000
+ dw MTRR_FIX_4K_F0000, MTRR_FIX_4K_F8000
+MTRR_TABLE_END label byte
+
+;----------------------------------------------
+align 16
+GDT_BASE:
+NULL_SEL equ $-GDT_BASE ;NULL Selector 0
+ dd 0, 0
+
+DATA_SEL equ $-GDT_BASE ; Selector 8, Data 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9300h
+
+CODE_SEL equ $-GDT_BASE ; Selector 10h, CODE 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9b00h
+
+; We only need this because Intel DebugSupport driver
+; (RegisterPeriodicCallback function) assumes that selector 0x20 is valid
+; The funciton sets 0x20 as a code selector in IDT
+;
+; To switch to 16 bit, Selectors SYS16_CODE_SEL and SYS16_DATA_SEL are used.
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9300h ;data, expand-up, notwritable, 32-bit
+
+; System code segment descriptor
+SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9b00h ;data, expand-up, writable, 32-bit
+SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
+ dd 0, 0
+SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
+ dd 0000FFFFh
+ dd 00cf9300h
+SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
+ dd 0000FFFFh
+ dd 00af9b00h
+SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]
+ dd 0, 0
+GDT_SIZE equ $-GDT_BASE ;Size of Descriptor Table
+
+GdtDescriptor:
+ dw GDT_SIZE - 1 ; GDT limit
+ dd offset GDT_BASE ; GDT base Relative to 4G.
+
+STARTUP_SEG ENDS
+
+end
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/x64/AmiX64Lib.cif b/Core/CPU/x64/AmiX64Lib.cif
new file mode 100644
index 0000000..5070b67
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.cif
@@ -0,0 +1,52 @@
+<component>
+ name = "AmiX64Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "AmiX64Lib"
+[files]
+"AmiX64Lib.sdl"
+"AmiX64Lib.mak"
+"x64CLib.c"
+"x64AsmLib\checkpoint.asm"
+"x64AsmLib\CPULib_CpuID.asm"
+"x64AsmLib\CPULib_DisableInterrupt.asm"
+"x64AsmLib\CPULib_EnableInterrupt.asm"
+"x64AsmLib\CPULib_GetInterruptState.asm"
+"x64AsmLib\CPULIB_GetPageTable.asm"
+"x64AsmLib\CPULib_LoadGdt.asm"
+"x64AsmLib\CPULib_LoadIdt.asm"
+"x64AsmLib\CPULib_LockByteDec.asm"
+"x64AsmLib\CPULib_LockByteInc.asm"
+"x64AsmLib\CPULib_Pause.asm"
+"x64AsmLib\CPULib_SaveGdt.asm"
+"x64AsmLib\CPULib_SaveIdt.asm"
+"x64AsmLib\DisableCacheInCR0.asm"
+"x64AsmLib\EnableCacheInCR0.asm"
+"x64AsmLib\EnableMachineCheck.asm"
+"x64AsmLib\GetCpuTimer.asm"
+"x64AsmLib\GetCsSegment.asm"
+"x64AsmLib\GetPowerOfTwo64.asm"
+"x64AsmLib\HltCpu.asm"
+"x64AsmLib\IoRead16.asm"
+"x64AsmLib\IoRead32.asm"
+"x64AsmLib\IoRead64.asm"
+"x64AsmLib\IoRead8.asm"
+"x64AsmLib\IoWrite16.asm"
+"x64AsmLib\IoWrite32.asm"
+"x64AsmLib\IoWrite64.asm"
+"x64AsmLib\IoWrite8.asm"
+"x64AsmLib\MemCpy.asm"
+"x64AsmLib\MemRead32.asm"
+"x64AsmLib\MemReadWrite32.asm"
+"x64AsmLib\MemSet.asm"
+"x64AsmLib\ReadCr3.asm"
+"x64AsmLib\ReadMsr.asm"
+"x64AsmLib\ReadRtdsc.asm"
+"x64AsmLib\WaitForever.asm"
+"x64AsmLib\WaitForSemaphore.asm"
+"x64AsmLib\WaitUntilZero32.asm"
+"x64AsmLib\WaitUntilZero8.asm"
+"x64AsmLib\WriteCr3.asm"
+"x64AsmLib\WriteMsr.asm"
+"x64AsmLib\MemCpy32.asm"
+<endComponent>
diff --git a/Core/CPU/x64/AmiX64Lib.mak b/Core/CPU/x64/AmiX64Lib.mak
new file mode 100644
index 0000000..e2cd482
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.mak
@@ -0,0 +1,63 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/x64Core/AmiX64Lib.mak 1 10/13/06 8:37p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 10/13/06 8:37p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/x64Core/AmiX64Lib.mak $
+#
+# 1 10/13/06 8:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiX64Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+AmiX64Lib : $(BUILD_DIR)\AmiX64Lib.mak AmiX64LibBin
+
+$(BUILD_DIR)\AmiX64Lib.mak : $(AmiX64Lib_DIR)\$(@B).cif $(AmiX64Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiX64Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+AmiDxeLibBin : $(BUILD_DIR)\AmiX64Lib.lib
+$(BUILD_DIR)\AmiX64Lib.lib : AmiX64Lib
+!ENDIF
+
+AmiX64LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiX64Lib.mak all\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/AmiX64Lib.sdl b/Core/CPU/x64/AmiX64Lib.sdl
new file mode 100644
index 0000000..79b7e36
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "AmiX64Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiX64Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AmiX64Lib_DIR"
+End
+
+MODULE
+ Help = "Includes AmiX64Lib.mak to Project"
+ File = "AmiX64Lib.mak"
+End
+
diff --git a/Core/CPU/x64/EfiJump.h b/Core/CPU/x64/EfiJump.h
new file mode 100644
index 0000000..61f371f
--- /dev/null
+++ b/Core/CPU/x64/EfiJump.h
@@ -0,0 +1,42 @@
+/*++
+
+Copyright (c) 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an x64 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+typedef struct {
+ UINT64 Rbx;
+ UINT64 Rsp;
+ UINT64 Rbp;
+ UINT64 Rdi;
+ UINT64 Rsi;
+ UINT64 R10;
+ UINT64 R11;
+ UINT64 R12;
+ UINT64 R13;
+ UINT64 R14;
+ UINT64 R15;
+ UINT64 Rip;
+ UINT32 MxCsr;
+ UINT8 XmmBuffer[160]; // XMM6-XMM15
+} EFI_JUMP_BUFFER;
+
+#endif
diff --git a/Core/CPU/x64/Foundationx64.cif b/Core/CPU/x64/Foundationx64.cif
new file mode 100644
index 0000000..cb10e7a
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Foundationx64"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "Foundationx64"
+[files]
+"Foundationx64.sdl"
+"Foundationx64.mak"
+"ProcessorAsms.Asm"
+"EfiJump.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"Processor.c"
+"Processor.h"
+<endComponent>
diff --git a/Core/CPU/x64/Foundationx64.mak b/Core/CPU/x64/Foundationx64.mak
new file mode 100644
index 0000000..488e672
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.mak
@@ -0,0 +1,65 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/x64/Foundationx64.mak 1 8/24/06 12:36p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/x64/Foundationx64.mak $
+#
+# 1 8/24/06 12:36p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Foundationx64.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+Foundationx64 : $(BUILD_DIR)\Foundationx64.mak Foundationx64Bin
+
+$(BUILD_DIR)\Foundationx64.mak : $(Foundationx64_DIR)\$(@B).cif $(Foundationx64_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(Foundationx64_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+FoundationBin : $(BUILD_DIR)\Foundationx64.lib
+$(BUILD_DIR)\Foundationx64.lib : Foundationx64
+!ENDIF
+
+
+Foundationx64Bin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Foundationx64.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/Foundationx64.sdl b/Core/CPU/x64/Foundationx64.sdl
new file mode 100644
index 0000000..bb61c1a
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "Foundationx64_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Foundationx64 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Foundationx64_DIR"
+End
+
+MODULE
+ Help = "Includes Foundationx64.mak to Project"
+ File = "Foundationx64.mak"
+End
+
diff --git a/Core/CPU/x64/MiscLib/Misc.asm b/Core/CPU/x64/MiscLib/Misc.asm
new file mode 100644
index 0000000..facdd89
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/Misc.asm
@@ -0,0 +1,124 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/Misc.asm 2 10/04/12 9:17a Davidhsieh $
+;
+; $Revision: 2 $
+;
+; $Date: 10/04/12 9:17a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/Misc.asm $
+;
+; 2 10/04/12 9:17a Davidhsieh
+; Add MpMtrrSynchUpEntry and MpMtrrSynchUpExit procedures
+;
+; 1 5/15/12 5:41a Davidhsieh
+;
+; 1 5/08/12 6:02a Dukeyeh
+; [TAG] EIP89382
+; [Category] Improvement
+; [Description] clear direction flag inside Timer callback function.
+; [Files] MiscX64Lib.cif
+; Misc.asm
+; MiscX64Lib.sdl
+; MiscX64Lib.mak
+;
+; 6 1/13/10 2:13p Felixp
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: Misc
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.code
+
+ClearDirectionFlag Proc
+ cld
+ ret
+ClearDirectionFlag endp
+
+MpMtrrSynchUpEntry PROC PUBLIC
+ ;
+ ; Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)
+ ;
+ mov rax, cr0
+ and rax, 0DFFFFFFFh
+ or rax, 040000000h
+ mov cr0, rax
+ ;
+ ; Flush cache
+ ;
+ wbinvd
+ ;
+ ; Clear PGE flag Bit 7
+ ;
+ mov rax, cr4
+ mov rdx, rax
+ and rax, 0FFFFFF7Fh
+ mov cr4, rax
+ ;
+ ; Flush all TLBs
+ ;
+ mov rax, cr3
+ mov cr3, rax
+
+ mov rax, rdx
+
+ ret
+
+MpMtrrSynchUpEntry ENDP
+
+MpMtrrSynchUpExit PROC PUBLIC
+ ;
+ ; Flush all TLBs the second time
+ ;
+ mov rax, cr3
+ mov cr3, rax
+ ;
+ ; Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)
+ ;
+ mov rax, cr0
+ and rax, 09FFFFFFFh
+ mov cr0, rax
+ ;
+ ; Set PGE Flag in CR4 if set
+ ;
+ mov cr4, rcx
+ ret
+
+MpMtrrSynchUpExit ENDP
+
+END
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.cif b/Core/CPU/x64/MiscLib/MiscX64Lib.cif
new file mode 100644
index 0000000..c05edf2
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "MiscX64Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\MiscLib"
+ RefName = "MiscX64Lib"
+[files]
+"Misc.asm"
+"MiscX64Lib.sdl"
+"MiscX64Lib.mak"
+<endComponent>
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.mak b/Core/CPU/x64/MiscLib/MiscX64Lib.mak
new file mode 100644
index 0000000..61e7446
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.mak
@@ -0,0 +1,74 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/MiscX64Lib.mak 1 5/15/12 5:41a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 5/15/12 5:41a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/MiscX64Lib.mak $
+#
+# 1 5/15/12 5:41a Davidhsieh
+#
+# 1 5/08/12 6:02a Dukeyeh
+# [TAG] EIP89382
+# [Category] Improvement
+# [Description] clear direction flag inside Timer callback function.
+# [Files] MiscX64Lib.cif
+# Misc.asm
+# MiscX64Lib.sdl
+# MiscX64Lib.mak
+#
+# 1 10/13/06 8:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: MiscX64Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+MiscX64Lib : $(BUILD_DIR)\MiscX64Lib.mak MiscX64LibBin
+
+$(BUILD_DIR)\MiscX64Lib.mak : $(MiscX64Lib_DIR)\$(@B).cif $(MiscX64Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MiscX64Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+AmiDxeLibBin : $(BUILD_DIR)\MiscX64Lib.lib
+$(BUILD_DIR)\MiscX64Lib.lib : MiscX64Lib
+!ENDIF
+
+MiscX64LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MiscX64Lib.mak all\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.sdl b/Core/CPU/x64/MiscLib/MiscX64Lib.sdl
new file mode 100644
index 0000000..a9c676e
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "MiscX64Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable MiscX64Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "MiscX64Lib_DIR"
+End
+
+MODULE
+ Help = "Includes MiscX64Lib.mak to Project"
+ File = "MiscX64Lib.mak"
+End
+
diff --git a/Core/CPU/x64/PeCoffLoaderEx.c b/Core/CPU/x64/PeCoffLoaderEx.c
new file mode 100644
index 0000000..ff216a7
--- /dev/null
+++ b/Core/CPU/x64/PeCoffLoaderEx.c
@@ -0,0 +1,87 @@
+/*++
+
+Copyright (c) 2005 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ x64 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+ Performs an x64 specific relocation fixup
+
+Arguments:
+ Reloc - Pointer to the relocation record
+ Fixup - Pointer to the address to fix up
+ FixupData - Pointer to a buffer to log the fixups
+ Adjust - The offset to adjust the fixup
+
+Returns:
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) ||
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Core/CPU/x64/PeCoffLoaderEx.h b/Core/CPU/x64/PeCoffLoaderEx.h
new file mode 100644
index 0000000..a3f78e0
--- /dev/null
+++ b/Core/CPU/x64/PeCoffLoaderEx.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ x64 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an x64 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/x64/Processor.c b/Core/CPU/x64/Processor.c
new file mode 100644
index 0000000..21a1649
--- /dev/null
+++ b/Core/CPU/x64/Processor.c
@@ -0,0 +1,146 @@
+/*++
+
+Copyright 2005 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+TransferControlSetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+TransferControlLongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+//
+// Table declarations
+//
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ TransferControlSetJump,
+ TransferControlLongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ FlushInstructionCacheFlush
+};
+
+
+EFI_STATUS
+EFIAPI
+InstallEfiPeiTransferControl(
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ This - Pointer to transfer control mechanism.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ This - Pointer to flush instruction cache mechanism.
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+ In the case of IA32, this flushing is not necessary and is thus not implemented.
+
+Arguments:
+
+ Pointer to CPU Architectural Protocol interface
+ Start adddress in memory to flush
+ Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CPU/x64/Processor.h b/Core/CPU/x64/Processor.h
new file mode 100644
index 0000000..cdf2992
--- /dev/null
+++ b/Core/CPU/x64/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the x64 processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
+
+#endif
diff --git a/Core/CPU/x64/ProcessorAsms.Asm b/Core/CPU/x64/ProcessorAsms.Asm
new file mode 100644
index 0000000..ebd8b03
--- /dev/null
+++ b/Core/CPU/x64/ProcessorAsms.Asm
@@ -0,0 +1,186 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2005 - 2007, Intel Corporation
+; All rights reserved. This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+; ProcessorAsms.Asm
+;
+; Abstract:
+; This is separated from processor.c to allow this functions to be built with /O1
+;
+;
+;------------------------------------------------------------------------------
+
+text SEGMENT
+
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter // rcx
+; Parameter - Parameter to pass in // rdx
+; NewStack - New Location of the stack // r8
+; NewBsp - New BSP // r9 - not used
+;
+; Returns:
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchStacks PROC PUBLIC
+
+ ; Adjust stack for
+ ; 1) leave 4 registers space
+ ; 2) let it 16 bytes aligned after call
+ sub r8, 20h
+ and r8w, 0fff0h ; do not assume 16 bytes aligned
+
+ mov rsp, r8 ; rsp = NewStack
+ mov r10, rcx ; save EntryPoint
+ mov rcx, rdx ; Arg1 = Parameter
+ call r10 ; r10 = copy of EntryPoint
+ ;
+ ; no ret as we have a new stack and we jumped to the new location
+ ;
+ ret
+
+SwitchStacks ENDP
+
+
+EFI_SUCCESS equ 0
+EFI_WARN_RETURN_FROM_LONG_JUMP equ 5
+
+;
+; Generated by h2inc run manually
+;
+_EFI_JUMP_BUFFER STRUCT 2t
+_rbx QWORD ?
+_rsp QWORD ?
+_rbp QWORD ?
+_rdi QWORD ?
+_rsi QWORD ?
+_r10 QWORD ?
+_r11 QWORD ?
+_r12 QWORD ?
+_r13 QWORD ?
+_r14 QWORD ?
+_r15 QWORD ?
+_rip QWORD ?
+_MxCsr DWORD ?
+_XmmBuffer DB 160 DUP (?)
+_EFI_JUMP_BUFFER ENDS
+
+EFI_JUMP_BUFFER TYPEDEF _EFI_JUMP_BUFFER
+
+
+;
+;Routine Description:
+;
+; This routine implements the x64 variant of the SetJump call. Its
+; responsibility is to store system state information for a possible
+; subsequent LongJump.
+;
+;Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+;Returns:
+;
+; EFI_SUCCESS
+;
+; EFI_STATUS
+; EFIAPI
+; TransferControlLongJump (
+; IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+; IN EFI_JUMP_BUFFER *Jump
+; );
+;
+; rcx - *This
+; rdx - JumpBuffer
+;
+PUBLIC TransferControlSetJump
+TransferControlSetJump PROC
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rbx, rbx
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rsp, rsp
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rbp, rbp
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rdi, rdi
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rsi, rsi
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r10, r10
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r11, r11
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r12, r12
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r13, r13
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r14, r14
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r15, r15
+ ; save non-volatile fp registers
+ stmxcsr (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
+ lea rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
+ movdqu [rax], xmm6
+ movdqu [rax + 10h], xmm7
+ movdqu [rax + 20h], xmm8
+ movdqu [rax + 30h], xmm9
+ movdqu [rax + 40h], xmm10
+ movdqu [rax + 50h], xmm11
+ movdqu [rax + 60h], xmm12
+ movdqu [rax + 70h], xmm13
+ movdqu [rax + 80h], xmm14
+ movdqu [rax + 90h], xmm15
+ mov rax, QWORD PTR [rsp+0]
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rip, rax
+ mov rax, EFI_SUCCESS
+ ret
+
+TransferControlSetJump ENDP
+
+;
+; EFI_STATUS
+; EFIAPI
+; TransferControlLongJump (
+; IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This, // rcx
+; IN EFI_JUMP_BUFFER *Jump // rdx
+; );
+;
+;
+PUBLIC TransferControlLongJump
+TransferControlLongJump PROC
+ ; load non-volatile fp registers
+ ldmxcsr (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
+ lea rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
+ movdqu xmm6, [rax]
+ movdqu xmm7, [rax + 10h]
+ movdqu xmm8, [rax + 20h]
+ movdqu xmm9, [rax + 30h]
+ movdqu xmm10, [rax + 40h]
+ movdqu xmm11, [rax + 50h]
+ movdqu xmm12, [rax + 60h]
+ movdqu xmm13, [rax + 70h]
+ movdqu xmm14, [rax + 80h]
+ movdqu xmm15, [rax + 90h]
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rbx, (EFI_JUMP_BUFFER PTR [rdx])._rbx
+ mov rsp, (EFI_JUMP_BUFFER PTR [rdx])._rsp
+ mov rbp, (EFI_JUMP_BUFFER PTR [rdx])._rbp
+ mov rdi, (EFI_JUMP_BUFFER PTR [rdx])._rdi
+ mov rsi, (EFI_JUMP_BUFFER PTR [rdx])._rsi
+ mov r10, (EFI_JUMP_BUFFER PTR [rdx])._r10
+ mov r11, (EFI_JUMP_BUFFER PTR [rdx])._r11
+ mov r12, (EFI_JUMP_BUFFER PTR [rdx])._r12
+ mov r13, (EFI_JUMP_BUFFER PTR [rdx])._r13
+ mov r14, (EFI_JUMP_BUFFER PTR [rdx])._r14
+ mov r15, (EFI_JUMP_BUFFER PTR [rdx])._r15
+ add rsp, 8 ;pop the eip
+ jmp QWORD PTR (EFI_JUMP_BUFFER PTR [rdx])._rip
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ ret
+TransferControlLongJump ENDP
+
+text ENDS
+END
diff --git a/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm b/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm
new file mode 100644
index 0000000..973357f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm
@@ -0,0 +1,80 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULIB_GetPageTable.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULIB_GetPageTable.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULIB_GetPageTable
+;
+; Description:
+; VOID* CPULIB_GetPageTable() retrieves the address of the page table.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID* address of the page table.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULIB_GetPageTable proc
+ mov rax, cr3
+ ret
+CPULIB_GetPageTable endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm b/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm
new file mode 100644
index 0000000..53719f2
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm
@@ -0,0 +1,130 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_CpuID.asm 2 11/11/11 3:40p Artems $
+;
+; $Revision: 2 $
+;
+; $Date: 11/11/11 3:40p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_CpuID.asm $
+;
+; 2 11/11/11 3:40p Artems
+; Bug fix: Verify pointer is not NULL, when return value
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_CpuID
+;
+; Description:
+; VOID CPULib_CpuID(IN UINT32 CpuIDIndex, IN UINT32 *pRegEAX,
+; IN UINT32 *pRegEBX, IN UINT32 *pRegECX, IN UINT32 *pRegEDX) issues the
+; CPUID instruction with the index provided and returns the register values.
+;
+; Input:
+; IN UINT32 CpuIDIndex
+; 32-bit CPUID index.
+;
+; IN UINT32 *pRegEAX
+; Value of EAX after CPUID instruction.
+;
+; IN UINT32 *pRegEBX
+; Value of EBX after CPUID instruction.
+;
+; IN UINT32 *pRegECX
+; Value of ECX after CPUID instruction.
+;
+; IN UINT32 *pRegEDX
+; Value of EDX after CPUID instruction.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_CpuID proc
+;rcx = CpuIDIndex
+;rdx = pRegEax
+;r8 = pRegEBX
+;r9 = pRegECX
+;[rsp + 8] = pRegEDX:DWORD
+
+ push rbx
+ mov r11, [rsp + 30h] ;pRegEDX
+ mov r10, r9 ;pRegECX
+ mov r9, r8 ;pRegEBX
+ mov r8, rdx ;pRegEAX
+
+ mov eax, ecx
+ mov ecx, [r10]
+ cpuid
+
+ or r8, r8
+ jz skip1
+ mov [r8], eax
+skip1:
+ or r9, r9
+ jz skip2
+ mov [r9], ebx
+skip2:
+ or r10, r10
+ jz skip3
+ mov [r10], ecx
+skip3:
+ or r11, r11
+ jz skip4
+ mov [r11], edx
+skip4:
+ pop rbx
+ ret
+CPULib_CpuID endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm b/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm
new file mode 100644
index 0000000..6c63f8a
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_DisableInterrupt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_DisableInterrupt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_DisableInterrupt
+;
+; Description:
+; VOID CPULib_DisableInterrupt() disables interrupts on the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_DisableInterrupt PROC PUBLIC
+; Disable Interrupt
+ cli
+ ret
+CPULib_DisableInterrupt ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm b/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm
new file mode 100644
index 0000000..bc43c62
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_EnableInterrupt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_EnableInterrupt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_EnableInterrupt
+;
+; Description:
+; VOID CPULib_EnableInterrupt() enables interrupts on the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_EnableInterrupt PROC PUBLIC
+; Enable Interrupt
+ sti
+ ret
+CPULib_EnableInterrupt ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm b/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm
new file mode 100644
index 0000000..436cba7
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_GetInterruptState.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_GetInterruptState.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_GetInterruptState
+;
+; Description:
+; BOOLEAN CPULib_GetInterruptState()returns the current CPU interrupt state.
+;
+; Input:
+; VOID.
+;
+; Output:
+; FALSE if interrupts are disabled; otherwise TRUE.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_GetInterruptState PROC PUBLIC
+ xor cl, cl
+ pushf ; push flags onto stack.
+ pop ax ; eax = flags.
+ bt ax, 9 ; IF (bit 9) if set, set carry flag.
+ ; Interrupts are allowed if IF is set.
+ adc cl, 0 ; CL = IF = CF.
+
+ mov al, cl ; Return value
+ ret
+CPULib_GetInterruptState ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm
new file mode 100644
index 0000000..1fc3c23
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadGdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadGdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LoadGdt
+;
+; Description:
+; VOID CPULib_LoadGdt(IN VOID *ptr) loads the GDT at the location pointed to
+; by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address of the GDT to be loaded.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LoadGdt proc
+ lgdt fword ptr [rcx]
+ ret
+CPULib_LoadGdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm
new file mode 100644
index 0000000..3c4afc8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadIdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadIdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LoadIdt
+;
+; Description:
+; VOID CPULib_LoadIdt(IN VOID *ptr) loads the IDT at the location provided
+; by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address of the IDT to be loaded.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LoadIdt proc
+ lidt fword ptr [rcx]
+ ret
+CPULib_LoadIdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm b/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm
new file mode 100644
index 0000000..433bd1b
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteDec.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteDec.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LockByteDec
+;
+; Description:
+; VOID CPULib_LockByteDec(IN UINT8 *ptr) locks the preceeding byte before
+; the address pointed to by ptr.
+;
+; Input:
+; IN UINT8 *ptr
+; Address to the byte which follows the desired byte to be locked.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LockByteDec proc
+ lock dec byte ptr [rcx]
+ ret
+CPULib_LockByteDec endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm b/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm
new file mode 100644
index 0000000..83addc8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteInc.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteInc.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LockByteInc
+;
+; Description:
+; VOID CPULib_LockByteInc(IN UINT8 *ptr) locks the next byte after the
+; address pointed to by ptr.
+;
+; Input:
+; IN UINT8 *ptr
+; Address to the byte which preceeds the desired byte to be locked.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LockByteInc proc
+ lock inc byte ptr [rcx]
+ ret
+CPULib_LockByteInc endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm b/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm
new file mode 100644
index 0000000..c7d2574
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm
@@ -0,0 +1,80 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_Pause.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_Pause.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_Pause
+;
+; Description:
+; VOID CPULib_Pause() performs the pause assembly instruction.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_Pause Proc
+ pause
+ ret
+CPULib_Pause endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm
new file mode 100644
index 0000000..28258cf
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveGdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveGdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_SaveGdt
+;
+; Description:
+; VOID CPULib_SaveGdt(IN VOID *ptr) stores the loaded GDT at the location
+; provided by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address to save the GDT. User is responsible for allocating the necessary
+; memory resources.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_SaveGdt proc
+ sgdt fword ptr [rcx]
+ ret
+CPULib_SaveGdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm
new file mode 100644
index 0000000..046b7f6
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveIdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveIdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_SaveIdt
+;
+; Description:
+; VOID CPULib_SaveIdt(IN VOID *ptr) stores the loaded IDT at the location
+; provided by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address to save the IDT. User is responsible for allocating the necessary
+; memory resources.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_SaveIdt proc
+ sidt fword ptr [rcx]
+ ret
+CPULib_SaveIdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm b/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm
new file mode 100644
index 0000000..c03cd1f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/DisableCacheInCR0.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/DisableCacheInCR0.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: DisableCacheInCR0
+;
+; Description:
+; VOID DisableCacheInCR0() disables the CPU cache using the CR0 register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+DisableCacheInCR0 PROC PUBLIC
+ wbinvd
+ mov rax, cr0
+ or eax, 060000000h ;SET CD, NW
+ mov cr0, rax
+ wbinvd ;Invalidate cache
+ ret
+DisableCacheInCR0 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm b/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm
new file mode 100644
index 0000000..7633a1f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableCacheInCR0.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableCacheInCR0.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableCacheInCR0
+;
+; Description:
+; VOID EnableCacheInCR0() enables the CPU cache using the CR0 register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableCacheInCR0 PROC PUBLIC
+; Enable cache
+ mov rax, cr0
+ and eax, 09fffffffh ;SET CD, NW
+ mov cr0, rax
+ wbinvd
+ ret
+EnableCacheInCR0 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm b/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm
new file mode 100644
index 0000000..b220afd
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableMachineCheck.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableMachineCheck.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableMachineCheck
+;
+; Description:
+; VOID EnableMachineCheck() sets the Machine Check Exception bit in CR4,
+; which enables machine check interrupts to occur.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableMachineCheck proc
+ mov rax, cr4
+ or eax, 1 SHL 6
+ mov cr4, rax
+ ret
+EnableMachineCheck endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm b/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm
new file mode 100644
index 0000000..f606744
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCpuTimer.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCpuTimer.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetCpuTimer
+;
+; Description:
+; UINT64 GetCpuTimer() returns the value of the CPU timer.
+;
+; Input:
+; None.
+;
+; Output:
+; UINT64 value of the CPU timer.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetCpuTimer proc
+ rdtsc
+ shl rdx,32
+ or rax, rdx
+ ret
+GetCpuTimer endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetCsSegment.asm b/Core/CPU/x64/x64AsmLib/GetCsSegment.asm
new file mode 100644
index 0000000..02138c3
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetCsSegment.asm
@@ -0,0 +1,79 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCsSegment.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCsSegment.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetCsSegment
+;
+; Description:
+; UINT16 GetCsSegment() retreives the value of the CS register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; UINT16 value of CS.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetCsSegment proc
+ mov ax, cs
+ ret
+GetCsSegment endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm b/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm
new file mode 100644
index 0000000..9cebe72
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetPowerOfTwo64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetPowerOfTwo64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetPowerOfTwo64
+;
+; Description:
+; UINT64 GetPowerOfTwo64(IN UINT64 Input) returns the highest bit set in
+; the provided UINT64 Input. Equivalent to 1 << log2(x).
+;
+; Input:
+; IN UINT64 Input
+; The 64-bit value to check for its highest bit.
+;
+; Output:
+; UINT64 value of the highest bit; if Input is 0, returns 0.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetPowerOfTwo64 proc
+ bsr rdx, rcx
+ xor rax, rax
+ bts rax, rdx
+ ret
+GetPowerOfTwo64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/HltCpu.asm b/Core/CPU/x64/x64AsmLib/HltCpu.asm
new file mode 100644
index 0000000..a8c8a6e
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/HltCpu.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/HltCpu.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/HltCpu.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: HltCpu
+;
+; Description:
+; VOID HltCpu() halts the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+HltCpu Proc
+@@:
+ cli
+ hlt
+ jmp @b
+ ret
+HltCpu endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead16.asm b/Core/CPU/x64/x64AsmLib/IoRead16.asm
new file mode 100644
index 0000000..3403a34
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead16.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead16.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead16.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead16
+;
+; Description:
+; UINT16 IoRead16(IN UINT16 Port) reads the 16-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 16-bits from.
+;
+; Output:
+; UINT16 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead16 proc
+ mov dx, cx
+ in ax, dx
+ ret
+IoRead16 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead32.asm b/Core/CPU/x64/x64AsmLib/IoRead32.asm
new file mode 100644
index 0000000..510a01f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead32.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead32
+;
+; Description:
+; UINT32 IoRead32(IN UINT16 Port) reads the 32-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 32-bits from.
+;
+; Output:
+; UINT32 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead32 proc
+ mov dx, cx
+ in eax, dx
+ ret
+IoRead32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead64.asm b/Core/CPU/x64/x64AsmLib/IoRead64.asm
new file mode 100644
index 0000000..ff1da50
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead64.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead64
+;
+; Description:
+; UINT32 IoRead64(IN UINT16 Port) reads the 64-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 64-bits from.
+;
+; Output:
+; UINT64 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead64 proc
+ mov dx, cx
+ in rax, dx
+ ret
+IoRead64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead8.asm b/Core/CPU/x64/x64AsmLib/IoRead8.asm
new file mode 100644
index 0000000..3dfd1fd
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead8.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead8.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead8.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead8
+;
+; Description:
+; UINT8 IoRead8(IN UINT16 Port) reads the 8-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 8-bits from.
+;
+; Output:
+; UINT8 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead8 proc
+ mov dx, cx
+ in al, dx
+ ret
+IoRead8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite16.asm b/Core/CPU/x64/x64AsmLib/IoWrite16.asm
new file mode 100644
index 0000000..2616d1a
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite16.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite16.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite16.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite16
+;
+; Description:
+; VOID IoWrite16(IN UINT16 Port, IN UINT16 Value) writes the 16-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 16-bits to.
+;
+; IN UINT16 Value
+; 16-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite16 proc
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+IoWrite16 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite32.asm b/Core/CPU/x64/x64AsmLib/IoWrite32.asm
new file mode 100644
index 0000000..98096d7
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite32.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite32
+;
+; Description:
+; VOID IoWrite32(IN UINT16 Port, IN UINT32 Value) writes the 32-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 32-bits to.
+;
+; IN UINT32 Value
+; 32-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite32 proc
+ mov eax, edx
+ mov dx, cx
+ out dx, eax
+ ret
+IoWrite32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite64.asm b/Core/CPU/x64/x64AsmLib/IoWrite64.asm
new file mode 100644
index 0000000..c38c832
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite64.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite64
+;
+; Description:
+; VOID IoWrite64(IN UINT16 Port, IN UINT64 Value) writes the 64-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 64-bits to.
+;
+; IN UINT64 Value
+; 64-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite64 proc
+ mov rax, rdx
+ mov dx, cx
+ out dx, rax
+ ret
+IoWrite64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite8.asm b/Core/CPU/x64/x64AsmLib/IoWrite8.asm
new file mode 100644
index 0000000..4bd5119
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite8.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite8.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite8.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite8
+;
+; Description:
+; VOID IoWrite8(IN UINT16 Port, IN UINT8 Value) writes the 8-bit Value to
+; the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 8-bits to.
+;
+; IN UINT8 Value
+; 8-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite8 proc
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+IoWrite8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemCpy.asm b/Core/CPU/x64/x64AsmLib/MemCpy.asm
new file mode 100644
index 0000000..a671ec8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemCpy.asm
@@ -0,0 +1,178 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy.asm 2 3/09/11 1:58p Felixp $
+;
+; $Revision: 2 $
+;
+; $Date: 3/09/11 1:58p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy.asm $
+;
+; 2 3/09/11 1:58p Felixp
+; MemCpy is updated to copy 8 bytes at a time (used to be 4)
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemCpy
+;
+; Description:
+; VOID MemCpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+; copies Count bytes of memory from Source to Destination.
+;
+; Input:
+; OUT VOID *pDestination
+; Memory address where data shall be copied. User is responsible for
+; allocating the necessary memory resources.
+;
+; IN VOID *pSource
+; Memory address from where data shall be copied.
+;
+; IN UINTN Count
+; Number of bytes to copy from pSource.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This function checks for overlapping of source and destination and
+; selects copy direction that prevents memory corruption.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+public memcpy
+memcpy:
+MemCpy proc
+ push rdi
+ push rsi
+ push rbx
+ pushf
+ mov rsi, rdx ; pSource
+ mov rdi, rcx ; pDestination
+ mov rcx, r8 ; Count
+ mov dl, 0
+ ; if pSource > pDestination CopyForward
+ mov rax, rsi
+ sub rax, rdi ; rax = pSource-pDestination
+ jnb CopyForward; if pSource-pDestination > 0 CopyForward
+ ; if pSource+Count < pDestination then CopyForward
+ lea rbx, [rsi+rcx] ; rbx = pSource + Count
+ neg rax ; rax = pDestination - pSource
+ cmp rbx, rdi
+ jb CopyForward ; if (pSource + Count < pDestination ) CopyForward
+ ; Copy Backward
+ mov rsi, rbx; rsi = pSource + Count
+ lea rdi, [rdi+rcx]; rdi = pDestination + Count
+ mov dl, 1; Flag to indicate that we are copying backward
+ std; set direction flag to copy backward
+CopyForward:
+ cmp rcx, 8 ; if (Counter<8) copy byte by byte
+ jb m8
+ cmp rax, 8 ; if (pDestination - pSource < 8) copy byte by byte
+ jb m8
+ ; if pSource and pDestination are not 8 byte aligned
+ ; Calculate 8-(Buffer%8), which is a number of bytes we have to copy to align the buffer
+ ; if this number if the same for source and destinations
+ ; copy several bytes to align them
+ ; otherwise proceed to QWORD copy
+ mov rax, rsi
+ mov rbx, rdi
+ and rax, 7
+ and rbx, 7
+ test dl, dl
+ jz skip1
+ dec rsi
+ dec rdi
+skip1:
+ cmp rax, rbx
+ jne m64
+ test rax, rax
+ jz m64
+ test dl, dl
+ jnz skip_nz1
+ neg rax
+ add rax, 8
+skip_nz1:
+ xchg rax, rcx
+ sub rax, rcx
+ rep movsb
+ mov rcx, rax
+m64:
+ test dl, dl
+ jz skip2
+ sub rsi, 7
+ sub rdi, 7
+skip2:
+ mov rax, rcx
+ shr rcx, 3
+ rep movsq
+ and rax, 7
+ jz MemCpuEnd
+ test dl, dl
+ jz skip3
+ add rsi, 8
+ add rdi, 8
+skip3:
+ mov rcx, rax
+m8:
+ test dl, dl
+ jz skip4
+ dec rsi
+ dec rdi
+skip4:
+ rep movsb
+MemCpuEnd:
+ popf
+ pop rbx
+ pop rsi
+ pop rdi
+ ret
+MemCpy endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemCpy32.asm b/Core/CPU/x64/x64AsmLib/MemCpy32.asm
new file mode 100644
index 0000000..a5886b3
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemCpy32.asm
@@ -0,0 +1,178 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy32.asm 1 10/17/11 1:03p Yakovlevs $
+;
+; $Revision: 1 $
+;
+; $Date: 10/17/11 1:03p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy32.asm $
+;
+; 1 10/17/11 1:03p Yakovlevs
+; [TAG] EIP71694
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemCpy32
+;
+; Description:
+; VOID MemCpy32(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+; copies Count bytes of memory from Source to Destination.
+;
+; Input:
+; OUT VOID *pDestination
+; Memory address where data shall be copied. User is responsible for
+; allocating the necessary memory resources.
+;
+; IN VOID *pSource
+; Memory address from where data shall be copied.
+;
+; IN UINTN Count
+; Number of bytes to copy from pSource.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This function checks for overlapping of source and destination and
+; selects copy direction that prevents memory corruption.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+public memcpy32
+memcpy32:
+MemCpy32 proc
+ push rdi
+ push rsi
+ push rbx
+ pushf
+ mov rsi, rdx ; pSource
+ mov rdi, rcx ; pDestination
+ mov rcx, r8 ; Count
+ mov dl, 0
+ ; if pSource > pDestination CopyForward
+ mov rax, rsi
+ sub rax, rdi ; rax = pSource-pDestination
+ jnb CopyForward; if pSource-pDestination > 0 CopyForward
+ ; if pSource+Count < pDestination then CopyForward
+ lea rbx, [rsi+rcx] ; rbx = pSource + Count
+ neg rax ; rax = pDestination - pSource
+ cmp rbx, rdi
+ jb CopyForward ; if (pSource + Count < pDestination ) CopyForward
+ ; Copy Backward
+ mov rsi, rbx; rsi = pSource + Count
+ lea rdi, [rdi+rcx]; rdi = pDestination + Count
+ mov dl, 1; Flag to indicate that we are copying backward
+ std; set direction flag to copy backward
+CopyForward:
+ cmp rcx, 4 ; if (Counter<4) copy byte by byte
+ jb m8
+ cmp rax, 4 ; if (pDestination - pSource < 4) copy byte by byte
+ jb m8
+ ; if pSource and pDestination are not 4 byte aligned
+ ; Calculate 4-(Buffer%4), which is a number of bytes we have to copy to align the buffer
+ ; if this number if the same for source and destinations
+ ; copy several bytes to align them
+ ; otherwise proceed to DWORD copy
+ mov rax, rsi
+ mov rbx, rdi
+ and rax, 3
+ and rbx, 3
+ test dl, dl
+ jz skip1
+ dec rsi
+ dec rdi
+skip1:
+ cmp rax, rbx
+ jne m32
+ test rax, rax
+ jz m32
+ test dl, dl
+ jnz skip_nz1
+ neg rax
+ add rax, 4
+skip_nz1:
+ xchg rax, rcx
+ sub rax, rcx
+ rep movsb
+ mov rcx, rax
+m32:
+ test dl, dl
+ jz skip2
+ sub rsi, 3
+ sub rdi, 3
+skip2:
+ mov rax, rcx
+ shr rcx, 2
+ rep movsd
+ and rax, 3
+ jz MemCpuEnd
+ test dl, dl
+ jz skip3
+ add rsi, 4
+ add rdi, 4
+skip3:
+ mov rcx, rax
+m8:
+ test dl, dl
+ jz skip4
+ dec rsi
+ dec rdi
+skip4:
+ rep movsb
+MemCpuEnd:
+ popf
+ pop rbx
+ pop rsi
+ pop rdi
+ ret
+MemCpy32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemRead32.asm b/Core/CPU/x64/x64AsmLib/MemRead32.asm
new file mode 100644
index 0000000..3f79a06
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemRead32.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemRead32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemRead32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemRead32
+;
+; Description:
+; UINT32 MemRead32(IN UINT32 *Address) reads and returns the 32-bit value
+; stored at the user provided address.
+;
+; Input:
+; IN UINT32 *Address
+; Address to read 32-bits from.
+;
+; Output:
+; UINT32 value stored at Address.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemRead32 proc
+ mov eax, [rcx]
+ ret
+MemRead32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm b/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm
new file mode 100644
index 0000000..a9ab5ba
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm
@@ -0,0 +1,93 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemReadWrite32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemReadWrite32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemReadWrite32
+;
+; Description:
+; VOID MemReadWrite32(IN UINT32 *Address, IN UINT32 Value, IN UINT32 Mask)
+; reads the 32-bit value stored at Address, ANDs it with Mask, ORs the result
+; with Value, then writes the result back to Address.
+;
+; Input:
+; IN UINT32 *Address
+; Address which shall be read from and subsequently written to.
+;
+; IN UINT32 Value
+; Value to be ORed with the value stored at Address after it has been ANDed
+; with the provided Mask.
+;
+; IN UINT32 Mask
+; Mask to be ANDed with the original value stored at Address.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemReadWrite32 proc
+ mov eax, [rcx]
+ and eax, r8D ;Mask
+ or eax, edx ;Value
+ mov [rcx], eax
+ ret
+MemReadWrite32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemSet.asm b/Core/CPU/x64/x64AsmLib/MemSet.asm
new file mode 100644
index 0000000..246b985
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemSet.asm
@@ -0,0 +1,127 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemSet.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemSet.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemSet
+;
+; Description:
+; VOID MemSet(IN VOID *pBuffer, IN UINTN Count, IN UINT8 Value) fills Count
+; bytes of memory in pBuffer with Value.
+;
+; Input:
+; IN VOID *pBuffer
+; The starting location in memory where to begin filling.
+;
+; IN UINTN Count
+; The number of bytes to fill with Value.
+;
+; IN UINT8 Value
+; The value to fill memory with starting at pBuffer.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemSet proc
+ push rdi
+ push rbx
+ mov rdi, rcx ; rdi = pBuffer
+ mov rcx, rdx ; rcx = Count
+ mov rax, r8 ; al = Value
+ ; fill EAX with the Value so that we can perform DWORD operatins
+ mov ah, al
+ mov bx,ax
+ shl rax,16
+ mov ax,bx
+ ; if Counter is less then 4, jump to byte copy
+ cmp rcx, 4
+ jb CopyByte
+ ; check if the Buffer is 4-bytes aligned
+ mov rdx,rdi
+ and rdx, 3
+ ; if the Buffer is 4-bytes aligned, jump to DWORD copy
+ jz CopyDword
+ ; Buffer is not 4-bytes aligned
+ ; Calculate 4-(Buffer%4), which is a number of bytes we have to copy before
+ ; Buffer will reach 4-bytes boundary, and perform byte copy
+ neg rdx
+ add rdx, 4
+ xchg rcx, rdx
+ sub rdx, rcx
+ rep stosb
+ mov rcx, rdx
+CopyDword:
+ ; perform DWORD copy
+ mov rdx, rcx
+ shr rcx, 2
+ rep stosd
+ ; copy the remainder
+ and rdx,3
+ mov rcx, rdx
+CopyByte:
+ rep stosb
+ ;;;
+ pop rbx
+ pop rdi
+ ret
+MemSet endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadCr3.asm b/Core/CPU/x64/x64AsmLib/ReadCr3.asm
new file mode 100644
index 0000000..ad90c20
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadCr3.asm
@@ -0,0 +1,79 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadCr3.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadCr3.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadCr3
+;
+; Description:
+; UINTN ReadCr3() reads the register CR3 and returns its value.
+;
+; Input:
+;
+; Output:
+; UINTN value stored in the CR3 register.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadCr3 PROC PUBLIC
+ mov rax, cr3
+ ret
+ReadCr3 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadMsr.asm b/Core/CPU/x64/x64AsmLib/ReadMsr.asm
new file mode 100644
index 0000000..3fbeff6
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadMsr.asm
@@ -0,0 +1,85 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadMsr.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadMsr.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadMsr
+;
+; Description:
+; UINT64 ReadMsr(UINT32 Msr) reads the CPU MSR index defined by Msr and
+; returns the value.
+;
+; Input:
+; IN UINT32 Msr
+; 32-bit MSR index to be read.
+;
+; Output:
+; UINT64 MSR value at MSR index, Msr.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadMsr Proc ;(UINT32 Msr)
+ rdmsr ;rcx = MSR
+ and rax, 0ffffffffh
+ shl rdx, 32
+ or rax, rdx ;rax = (rdx << 32) | eax
+ ret
+ReadMsr endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm b/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm
new file mode 100644
index 0000000..078964c
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadRtdsc.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadRtdsc.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadRtdsc
+;
+; Description:
+; UINT64 ReadRtdsc() retrieves the time stamp counter.
+;
+; Input:
+; VOID.
+;
+; Output:
+; UINT64 value of the time stamp counter.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadRtdsc Proc
+ rdtsc
+ shl rdx,32
+ or rax, rdx
+ ret
+ReadRtdsc endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm b/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm
new file mode 100644
index 0000000..a5efa82
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm
@@ -0,0 +1,88 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForSemaphore.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForSemaphore.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitForSemaphore
+;
+; Description:
+; VOID WaitForSemaphore(IN volatile UINT8 *Semaphore) waits for the
+; semaphore to become available; once available, it claims the semaphore and
+; returns.
+;
+; Input:
+; IN volatile UINT8 *Semaphore
+; Pointer to the desired semaphore.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitForSemaphore Proc
+ mov al, 1
+@@:
+ xchg al, [rcx]
+ or al, al
+ pause
+ jnz @b
+ ret
+WaitForSemaphore endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitForever.asm b/Core/CPU/x64/x64AsmLib/WaitForever.asm
new file mode 100644
index 0000000..c010643
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitForever.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForever.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForever.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitForever
+;
+; Description:
+; VOID WaitForever() performs an infinite loop which does nothing.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitForever Proc
+@@:
+ Pause
+ jmp @b
+ ret
+WaitForever endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm b/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm
new file mode 100644
index 0000000..cdda323
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm
@@ -0,0 +1,86 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero32.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero32.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitUntilZero32
+;
+; Description:
+; VOID WaitUntilZero32(IN volatile UINT32 *Value) waits until the UINT32
+; value stored at the Value address becomes 0, then continues.
+;
+; Input:
+; IN volatile UINT32 *Value
+; Address of the UINT32 value to be monitored.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitUntilZero32 Proc
+@@:
+ mov eax, [rcx]
+ or eax, eax
+ pause
+ jnz @b
+ ret
+WaitUntilZero32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm b/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm
new file mode 100644
index 0000000..b2c5f4d
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm
@@ -0,0 +1,86 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero8.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero8.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitUntilZero8
+;
+; Description:
+; VOID WaitUntilZero8(IN volatile UINT8 *Value) waits until the byte stored
+; at Value becomes 0, then continues.
+;
+; Input:
+; IN volatile UINT8 *Value
+; Address of the byte value to be monitored.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitUntilZero8 Proc
+@@:
+ mov al, [rcx]
+ or al, al
+ pause
+ jnz @b
+ ret
+WaitUntilZero8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WriteCr3.asm b/Core/CPU/x64/x64AsmLib/WriteCr3.asm
new file mode 100644
index 0000000..d028b07
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WriteCr3.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteCr3.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteCr3.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WriteCr3
+;
+; Description:
+; VOID WriteCr3(IN UINTN CR3) writes the provided value to the CR3 register.
+;
+; Input:
+; IN UINTN CR3
+; Value to be written to the CR3 register.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WriteCr3 PROC PUBLIC
+ mov cr3, rcx
+ ret
+WriteCr3 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WriteMsr.asm b/Core/CPU/x64/x64AsmLib/WriteMsr.asm
new file mode 100644
index 0000000..b181a5b
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WriteMsr.asm
@@ -0,0 +1,89 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteMsr.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteMsr.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WriteMsr
+;
+; Description:
+; VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value) writes the Value to the
+; supplied MSR index, Msr.
+;
+; Input:
+; IN UINT32 Msr
+; 32-bit MSR index to be written to.
+;
+; IN UINT64 Value
+; Value to be written to MSR index.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WriteMsr proc
+ ;rcx = MSR
+ mov rax, rdx ;rax = rdx = Value
+ and rax, 0ffffffffh ;Lower 32 bit MSR Value
+ shr rdx, 32 ;Upper 32 bit MSR Value
+ wrmsr
+ ret
+WriteMsr endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/checkpoint.asm b/Core/CPU/x64/x64AsmLib/checkpoint.asm
new file mode 100644
index 0000000..38edb52
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/checkpoint.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/checkpoint.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/checkpoint.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: checkpoint
+;
+; Description:
+; VOID checkpoint(IN UINT8 c) writes the value c to port 0x80.
+;
+; Input:
+; IN UINT8 c
+; The value/checkpoint to write to 0x80.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This routine should only be used if the PROGRESS_CODE or
+; PEI_PROGRESS_CODE macros are unavailable.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+checkpoint proc
+ mov al, cl
+ out 80h,al
+ ret
+checkpoint endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64CLib.c b/Core/CPU/x64/x64CLib.c
new file mode 100644
index 0000000..ad96411
--- /dev/null
+++ b/Core/CPU/x64/x64CLib.c
@@ -0,0 +1,328 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64CLib.c 4 7/10/09 9:30a Felixp $
+//
+// $Revision: 4 $
+//
+// $Date: 7/10/09 9:30a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64CLib.c $
+//
+// 4 7/10/09 9:30a Felixp
+// Function headers are added.
+//
+// 3 10/09/06 10:11a Felixp
+// MemCpy/MemSet replaced with assembler routines
+//
+// 2 8/25/06 10:52a Felixp
+// memcpy, memset functions updated with the volotile qualifier to
+// restrain compiler optimization.
+//
+// 1 8/24/06 12:57p Felixp
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: x64CLib.c
+//
+// Description:
+// Generic CPU library functions for the x64 architecture.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <efi.h>
+
+//*************************************************************************
+// Math
+//*************************************************************************
+
+//*************************************************************************
+//<AMI_GHDR_START>
+//
+// Name: Math_64_Bit_Functions
+//
+// Description:
+// Math functions involving 64-bit input parameters designed to be usable on
+// both 32-bit and 64-bit platforms.
+//
+// Fields: Header Function Description
+// ------------------------------------------------------------------
+// AmiLib Shr64 Shift 64-bit value right.
+// AmiLib Shl64 Shift 64-bit value left.
+// AmiLib Div64 Divide 64-bit value by a 31-bit value.
+// AmiLib Mul64 Multiply 64-bit value by a 32-bit value.
+// AmiLib GetPowerOfTwo64 Determine the highest set bit in a 64-bit value.
+//
+// Notes:
+// Header details which header file contains the function prototype for
+// the above functions. Append .h to the given name.
+//
+//<AMI_GHDR_END>
+//*************************************************************************
+
+//*************************************************************************
+//<AMI_GHDR_START>
+//
+// Name: CPU_Functions
+//
+// Description:
+// CPU related functions defined in the AMI library.
+//
+// Fields: Header Function Description
+// ------------------------------------------------------------------
+// None CPULib_CpuID Perform the cpuid assembly instruction.
+// None CPULib_DisableInterrupt Disable interrupts.
+// None CPULib_EnableInterrupt Enable interrupts.
+// None CPULib_GetInterruptState Get current interrupt state (enabled or disabled).
+// None CPULIB_GetPageTable Retrieve address of the page table.
+// None CPULib_LoadGdt Load GDT.
+// None CPULib_LoadIdt Load IDT.
+// None CPULib_LockByteDec Lock preceeding byte.
+// None CPULib_LockByteInc Lock following byte.
+// None CPULib_Pause Pause CPU.
+// None CPULib_SaveGdt Save GDT at provided location.
+// None CPULib_SaveIdt Save IDT at provided location.
+// None DisableCacheInCR0 Disable CPU cache using CR0.
+// None EnableCacheInCR0 Enable CPU cache using CR0.
+// None EnableMachineCheck Enable machine check exception bit in CR4.
+// AmiLib GetCpuTimer Retrieve the CPU timer's value.
+// None GetCsSegment Retrieve the code segment.
+// None HltCpu Halt the CPU.
+// None WaitForever Perform infinite loop.
+// None WaitForSemaphore Wait for semaphore to become available. then take control.
+// None WaitUntilZero32 Wait until a 32-bit memory region becomes zero.
+// None WaitUntilZero8 Wait until an 8-bit meomry region becomes zero.
+// None WriteMsr Write a value to a MSR.
+// None ReadMsr Read value from a MSR.
+// AmiLib WriteCr3 Write a value to CR3.
+// AmiLib ReadCr3 Read value from CR3.
+// None ReadRtdsc Retrieve the time stamp counter.
+//
+// Notes:
+// Header details which header file contains the function prototype for
+// the above functions. Append .h to the given name.
+//
+//<AMI_GHDR_END>
+//*************************************************************************
+
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Shr64
+//
+// Description:
+// UINT64 Shr64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// right the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted.
+//
+// IN UINT8 Shift
+// The number of bits to shift right.
+//
+// Output:
+// UINT64 Value shifted right Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Shr64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ return Value>>Shift;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Shl64
+//
+// Description:
+// UINT64 Shl64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// left the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted left.
+//
+// IN UINT8 Shift
+// The number of bits to shift.
+//
+// Output:
+// UINT64 Value shifted left Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Shl64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ return Value<<Shift;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Div64
+//
+// Description:
+// UINT64 Div64(IN UINT64 Dividend, IN UINTN Divisor,
+// OUT UINTN *Remainder OPTIONAL) divides a 64-bit number, Dividend, by the
+// Divisor, which can be up to 31-bits.
+//
+// Input:
+// IN UINT64 Dividend
+// The 64-bit number to be divided.
+//
+// IN UINT Divisor
+// The number to divide Dividend by; may not exceed 31-bits in size.
+//
+// OUT UINTN *Remainder OPTIONAL
+// The remainder of the division. Provide NULL if undesired; otherwise user
+// is responsible for handling the necessary memory resources.
+//
+// Output:
+// UINT64 result of dividing Dividend by Divisor.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Div64 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result = Dividend/Divisor;
+ if (Remainder) *Remainder=Dividend%Divisor;
+ return Result;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Mul64
+//
+// Description:
+// UINT64 Mul64(IN UINT64 Value64, IN UINTN Value32) multiplies a 64-bit
+// number by a 32-bit number and returns the 64-bit result.
+//
+// Input:
+// IN UINTN64 Value64
+// The 64-bit number to multiply by.
+//
+// IN UINTN Value32
+// The 32-bit number to multiply by.
+//
+// Output:
+// UINT64 result of multiplying Value64 by Value32.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Mul64(
+ IN UINT64 Value64,
+ IN UINTN Value32
+ )
+{
+ return Value64*Value32;
+}
+
+//*************************************************************************
+// Memory Operations
+//*************************************************************************
+
+VOID MemSet(VOID* pBuffer, UINTN Count, UINT8 Value);
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: memset
+//
+// Description:
+// VOID memset(IN VOID *pBuffer, IN UINT8 Value, IN UINTN Count) is a
+// wrapper for MemSet which fills Count bytes of memory in pBuffer with
+// Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// MemSet
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID memset(VOID* pBuffer, UINTN Value, UINTN Count)
+{
+ MemSet(pBuffer,Count,(UINT8)Value);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/x64/x64Core.cif b/Core/CPU/x64/x64Core.cif
new file mode 100644
index 0000000..0d92f09
--- /dev/null
+++ b/Core/CPU/x64/x64Core.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "x64 Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "x64Core"
+[files]
+"x64Core.sdl"
+"x64rules.mak"
+<endComponent>
diff --git a/Core/CPU/x64/x64Core.sdl b/Core/CPU/x64/x64Core.sdl
new file mode 100644
index 0000000..389aa0f
--- /dev/null
+++ b/Core/CPU/x64/x64Core.sdl
@@ -0,0 +1,112 @@
+TOKEN
+ Name = "x64_BUILD"
+ Value = "0"
+ Help = "Main switch to enable x64 support in Project\DO REBUILD ALL AFTER CHANGING THIS SWITCH!!!"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "GLOBAL_DEFINES_x64"
+ Value = "/DEFIx64 /DEFIX64"
+ Help = "Global x64-specific macro definitions. Added to CFLAGSx64 and AFLAGSx64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CC"
+ Value = "$(SILENT)$(CCX64DIR)\CL"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LINK"
+ Value = "$(SILENT)$(CCX64DIR)\LINK"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LIBEXE"
+ Value = "$(SILENT)$(CCX64DIR)\LINK /LIB"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CCPEI"
+ Value = "$(SILENT)$(CCX86DIR)\CL"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LINKPEI"
+ Value = "$(SILENT)$(CCX86DIR)\LINK"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LIBEXEPEI"
+ Value = "$(SILENT)$(CCX86DIR)\LINK /LIB"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CFLAGSx64"
+ Value = "/GS- $(GLOBAL_DEFINES_x64)"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASMx64"
+ Value = "$(SILENT)$(CCX64DIR)\ML64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "AFLAGSx64"
+ Value = "$(GLOBAL_DEFINES_x64) /Cp"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LFLAGSx64"
+ Value = "/MACHINE:AMD64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CP"
+ Value = "$(SILENT)$(CCX64DIR)\CL /nologo /EP"
+ Help = "C preprocessor"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "x64Core_DIR"
+End
+
+ELINK
+ Name = "x64"
+ Parent = "IA32"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(x64Core_DIR)\x64rules.mak"
+ Parent = "$(IA32Core_DIR)\IA32rules.mak"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/CPU/x64/x64rules.mak b/Core/CPU/x64/x64rules.mak
new file mode 100644
index 0000000..ed1ab3c
--- /dev/null
+++ b/Core/CPU/x64/x64rules.mak
@@ -0,0 +1,86 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/x64Core/x64rules.mak 3 8/02/07 1:33a Felixp $
+#
+# $Revision: 3 $
+#
+# $Date: 8/02/07 1:33a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/x64Core/x64rules.mak $
+#
+# 3 8/02/07 1:33a Felixp
+# minor modification to use newly defined COMPONENT_BUILD_RULES macro
+# defined in rules.mak
+#
+# 2 3/13/07 11:53a Felixp
+# Global and CPU architecture specific macros are now passed
+# to C preprocessor (used during DepEx and VFR compilation)
+#
+# 1 10/13/06 8:31p Felixp
+#
+# 3 9/05/06 6:03p Felixp
+# define PROCESSOR is IA32 when building PEI components in x64 build.
+#
+# 2 8/25/06 11:12a Felixp
+#
+# 1 8/24/06 12:57p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: x64rules.mak
+#
+# Description: Defines x64-specific build rules.
+# This file is included into the template makefile rules.mak
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(COMPONENT_BUILD_RULES)"=="PEI"
+# IA32 Build
+CC = $(CCPEI)
+LINK = $(LINKPEI)
+LIBEXE=$(LIBEXEPEI)
+
+LIB_BUILD_DIR=$(BUILD_ROOT)\IA32
+!UNDEF PROCESSOR
+PROCESSOR=IA32
+!INCLUDE $(IA32Core_DIR)\IA32rules.mak
+
+!ELSE
+# x64 Build
+ASM=$(ASMx64)
+
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) $(CFLAGSx64)
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) $(LFLAGSx64)
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) $(AFLAGSx64)
+EXTRA_AFLAGS16=$(EXTRA_AFLAGS16) $(GLOBAL_DEFINES_x64)
+CPFLAGS=$(CPFLAGS) $(GLOBAL_DEFINES_x64)
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file