summaryrefslogtreecommitdiff
path: root/Chipset/NB/NBDxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'Chipset/NB/NBDxe.c')
-rw-r--r--Chipset/NB/NBDxe.c4650
1 files changed, 4650 insertions, 0 deletions
diff --git a/Chipset/NB/NBDxe.c b/Chipset/NB/NBDxe.c
new file mode 100644
index 0000000..15dbbd0
--- /dev/null
+++ b/Chipset/NB/NBDxe.c
@@ -0,0 +1,4650 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/BIN/Chipset/Intel/NorthBridge/Haswell/Intel SystemAgent NB Chipset/NBDxe.c 50 12/02/14 3:20a Dennisliu $
+//
+// $Revision: 50 $
+//
+// $Date: 12/02/14 3:20a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Intel/NorthBridge/Haswell/Intel SystemAgent NB Chipset/NBDxe.c $
+//
+// 50 12/02/14 3:20a Dennisliu
+// [TAG] EIP194524
+// [Category] Spec Update
+// [Description] Shark Bay SA Reference Code Production Version 1.9.0
+//
+// 49 5/28/14 3:03a Dennisliu
+// [TAG] EIP161790
+// [Category] Improvement
+// [Description] DRAM Init BIT should be set after saving MRC S3 data to
+// NVRAM in DXE Phase as Intel suggested.
+// [Files] NBPei.c; NBDxe.c;
+//
+// 48 5/13/14 10:40p Dennisliu
+// [TAG] EIP167027
+// [Category] Improvement
+// [Description] [SharkBay Aptio4]Variable's attribute needs to be
+// reviewed by SA component driver
+// [Files] NBDXEBoard.c; IntelSaGopSetup.c; IntelSaGopPolicy.c;
+// NBDxe.c; NbPciCSP.c; PciHostBridge.c;
+//
+// 47 7/16/13 6:57a Jeffch
+// [TAG] None
+// [Severity] Improvement
+// [Description] Remove same offset acpi device.
+// [Files] NBDXE.c;
+//
+// 46 7/09/13 4:23a Ireneyang
+// [TAG] EIP128014
+// [Category] BrugFix
+// [Symptom] When populating PC3L DIMM x2 or upper DIMM slot only,
+// DMI type17 has wrong values.
+// [RootCause] When using Dimm with SPD funciton, there's no need to
+// use when using memorydown way to get spd data.
+// [Solution] Only when using memorydown Dimm needs to get SPD data.
+// [Files] NBDxe.c;
+//
+// 45 5/24/13 6:21a Jeffch
+// [TAG] None
+// [Severity] BugFix
+// [Description] Fix smbios type 17 data is incorrect for memory down
+// system .
+// [Files] NBDxe.c;
+//
+// 44 4/01/13 11:47p Ireneyang
+// # [TAG] None
+// [Severity] Improvement
+// [Description] Reduce boot time through PEG.
+// [Files] NB.mak; NBDxe.c; NBPEI.c; NBPPI.h; Sa.asl;
+// PcieComplex.c; GraphicsInit.c; PciExpressInit.c;
+//
+// 43 3/15/13 1:56a Ireneyang
+// [TAG] EIP118133
+// [Severity] BugFix
+// [Description] Fix and restructure PlatformConfig setting of SA policy.
+// [Files] NBDxe.c; GetSetupData.c; NbSetupData.h;
+//
+// 42 3/12/13 2:30a Ireneyang
+// [TAG] None
+// [Severity] Improvement
+// [Description] Remove related SaSsdt acpi data to DSDT
+// [Files] SaInit.c; INTELGFX.ASL; Sa.asl; SaSsdt.asl;
+// SaSsdtTables.sdl; NBDxe.c; NB.mak;
+//
+// 41 3/07/13 2:20a Ireneyang
+// [TAG] None
+// [Severity] Bug Fix
+// [Description] Intel Display Device disappear after S3 resume.
+// [Files] NBDXE.c;
+//
+// 39 2/09/13 10:23a Jeffch
+// [TAG] None
+// [Severity] Spec update
+// [Description] Update SA RC 1.1.0
+// [Files] NBPei.c; GetSetupData.c; NbSetupData.h; NBDXE.c;
+//
+// 38 1/28/13 5:53a Jeffch
+// [TAG] None
+// [Severity] Spec update
+// [Description] Update SA RC 1.0.
+// [Files] NBPei.c; GetSetupData.c; NbSetupData.h; NBDXE.c;
+// NB.sd; NB.uni; NBDxeBoard.c
+//
+// 37 1/11/13 1:49a Jeffch
+// [TAG] None
+// [Severity] Bug Fix
+// [Description] Fixed Peg error log init bug.
+// [Files] NBDXE.c;
+//
+// 36 1/10/13 6:00a Jeffch
+// [TAG] None
+// [Severity] Bug Fix
+// [Description] Fixed not program HDA codec for SaHDAVerbtable link bug.
+// [Files] NBDXE.c; GetSetupData.c; NbSetupData.h
+//
+// 35 1/03/13 7:30a Jeffch
+// [TAG] None
+// [Severity] Improvement
+// [Description] added SaHDAVerbtable link to OEM.
+// [Files] NBDxe.c; NbSetupData.h; GetSetupData.c;
+//
+// 34 12/24/12 3:16a Jeffch
+// [TAG] None
+// [Category] Bug Fix
+// [Description] fixed XTU not have create XMP GACI table.
+// [Files] NBDxe.c;
+//
+// 33 12/24/12 3:06a Jeffch
+// [TAG] None
+// [Category] Bug Fix
+// [Description] fixed XTU build fail issue.
+// [Files] NBDxe.c;
+//
+// 32 12/24/12 2:55a Jeffch
+// [TAG] None
+// [Category] Improvement
+// [Description] added ULT SKU auto disable PEG.
+// [Files] NBPei.c; NBDxe.c; NbPlatform.h; NB.sd;
+// [TAG] None
+// [Category] Bug Fix
+// [Description] Remove tRPab and fixed XTU build fail issue.
+// [Files] NBPei.c; NBDxe.c; NB.sd;
+//
+// 31 12/22/12 2:28a Jeffch
+// [TAG] None
+// [Severity] Bug Fix
+// [Description] Fxied anyway show Memory Timing default value.
+// [Files] NBPei.c;
+//
+// 30 12/19/12 7:15a Jeffch
+// [TAG] VddVoltage
+// [Severity] Bug Fix
+// [Description] Fixed show error Memory Voltage value.
+// [Files] NBDxe.c;
+//
+// 29 12/18/12 5:14a Jeffch
+// [TAG] None
+// [Severity] Spec update
+// [Description] Update SA RC 0.81.
+// [Files] NBDxe.c; NBPei.c
+//
+// 28 12/14/12 5:29a Jeffch
+// // [TAG] None
+// // [Severity] Important
+// // [Description] Show memory voltage.
+// // [Files] NB.sd; NB.uni; NBDxe.c.
+//
+// 27 12/03/12 5:57a Jeffch
+// [TAG] None
+// [Category] Improvement
+// [Description] optimize DetectNonComplaint function.
+// [Description] NBPEI.c, NBPPI.h, NBDxe.c
+//
+// 2 11/29/12 3:41a Jeffch
+//
+// 26 11/29/12 2:32a Jeffch
+// [TAG] None
+// [Category] Improvement
+// [Description] added bootime check IGFX Available.
+// [Files] NBDxe.c; NbPlatform.h; NB.sd;
+//
+// 23 11/20/12 2:57a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] Update SA RC 0.80.
+// [Files] NBDxe.c; NBPei.c
+//
+// 22 11/14/12 5:38a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] Update XTU4.x function
+// [Files] NBPei.c; GetSetupData.c; NbSetupData.h; NBDXE.c; NB.sd;
+// NB.uni
+//
+// 21 11/07/12 6:22a Jeffch
+// [TAG] EIP106013
+// [Severity] Important
+// [Description] Sound and image abnormal with HDMI.
+// [Files] NBDxe.c;
+//
+// 20 10/30/12 7:02a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] Update SA RC 0.72.
+// [Files] NBDxe.c; NBPei.c
+//
+// 19 10/16/12 9:39a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] SA RC 0.71 for support ULT.
+// [Files] NBDxe.c;
+//
+// 18 10/14/12 5:17a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] Follow SA RC 0.71.
+// [Files] NBPei.c, NBDxe.c; NBGeneric.c; NBCspLib.h; NBSetup.c;
+// Nb.sd; GetSetupData.c
+//
+// 17 10/14/12 12:22a Jeffch
+// [TAG] None
+// [Severity] Important
+// [Description] Update by XTU4.0.
+// [Files] NBPei.c, NBDxe.c, NBCspLib.h, NBGeneric.c
+// [TAG] None
+// [Severity] Important
+// [Description] Follow Update by Mahobay.
+// [Files] NBPei.c, NBDxe.c;
+//
+// 16 9/28/12 4:12a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] BDAT function support.
+// [Files] NB.sd, NBDxe.c, NBPEI.c, SystemAgent.sdl,
+// BdatAccessHandler.sdl
+//
+// 15 9/12/12 6:17a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Restore Performance Tuning the skip part
+// [Files] NBDxe.c
+//
+// 14 8/31/12 2:32a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Update Board ID for Haswell platform.
+// [Files] NBDxe.c
+//
+// 13 8/24/12 8:13a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Corrected GTT reference define.
+// [Files] NBDxe.c, NBPEI.c
+//
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Remove useless iME_SUPPORT.
+// [Files] NBDxe.c
+//
+// 12 8/14/12 4:32a Yurenlai
+// [TAG] None
+// [Severity] Important
+// [Description] Change for SystemAgent RefCode Revision: 0.6.1.
+// [Files] NB.sdl, NB.sd, NBCSP.CIF, NBDxe.c, NB.ASL, SaAudio.asl
+//
+// 11 7/27/12 8:38a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Description] IGfx Fource Disable Support.
+// [Files] GetSetupData.c, NB.sdl, NB.sd, NB.uni, NbSetupData.h,
+// NBDxe.c, NBPEI.c
+//
+// [TAG] None
+// [Category] Improvement
+// [Description] Adjusted NB policy debault.
+// [Files] NB.sd, NBDxe.c
+//
+// [TAG] None
+// [Category] Improvement
+// [Description] Change to before Dxe SaInit to set maximum payload.
+// [Files] NBDxe.c
+//
+// 10 7/03/12 6:44a Yurenlai
+// [TAG] None
+// [Severity] Important
+// [Description] Change for SystemAgent RefCode Revision: 0.6.0.
+// [Files] NBPEI.DXS, NB.sd, NBDxe.c, NBPEI.c
+//
+// 9 7/03/12 6:39a Yurenlai
+// [TAG] None
+// [Severity] Important
+// [Description] Change the Save/Restore NB Registers position.
+// [Files] NB.ASL, NBAcpi.c, NBDxe.c
+//
+// 8 6/14/12 4:56a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Description] Set Max Payload Size for EDS.
+// [Description] NBDxe.c
+//
+// 7 6/14/12 4:55a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Description] Fix some devices work abnormal in the PEG slot.
+// [Description] NBDxe.c
+//
+// 6 4/26/12 2:52a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Adjust Intel System Agent module the Setup item and
+// Policy.
+// [Description] GetSetupData.c, NB.sdl, NB.sd, NB.uni, NBDxe.c,
+// NBPEI.c,
+// NBSetup.c, NBSetupReset.c, NbSetupData.h
+//
+// 5 4/05/12 5:45a Yurenlai
+// [TAG] None
+// [Category] New Feature
+// [Severity] Normal
+// [Description] Enabled GDXC feature.
+// [Files] NBDxe.c, NBPEI.c
+//
+// 3 4/05/12 5:12a Yurenlai
+// [TAG] None
+// [Category] Improvement
+// [Severity] Important
+// [Description] Correct the Memory Info.
+// [Files] NBDxe.c
+//
+// 2 4/05/12 2:34a Yurenlai
+// [TAG] EIP87103
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Change for SystemAgent RefCode Revision: 0.5.5 .
+// [Files] NBDxe.c, NBPEI.c, NBSMI.C, NBGeneric.cm NB.sd, NBSetup.c,
+// GetSetupData.c, NbSetupData.h
+//
+// 1 2/08/12 4:34a Yurenlai
+// Intel Haswell/NB eChipset initially releases.
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NBDXE.C
+//
+// Description: This file contains code for North Bridge initialization
+// in the DXE stage
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//----------------------------------------------------------------------------
+// Include(s)
+//----------------------------------------------------------------------------
+
+#include <Efi.h>
+#include <Token.h>
+#include <DXE.h>
+#include <AmiDxeLib.h>
+#include <AmiHobs.h>
+#include <Setup.h>
+#include <AmiCspLib.h>
+#include <PciBus.h>
+//#include "NbS3Save.h"
+#include <Acpi20.h>
+#include <AMIVfr.h>
+#include <ppi\NBPPI.h>
+// Consumed Protocols
+#include <Protocol\PciRootBridgeIo.h>
+#include <Protocol\NBPlatformData.h>
+
+#if ACPI_SUPPORT
+ #if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ #include <Protocol\AcpiSystemDescriptionTable.h>
+ #else
+ #include <Protocol\AcpiSupport.h>
+ #endif
+#endif
+
+#define _SA_COMMON_DEFINITIONS_H_
+#include <Protocol\SaPlatformPolicy\SaPlatformPolicy.h>
+#include <Protocol\AmiUsbController.h>
+#include <SaDataHob\SaDataHob.h>
+#include <Hob.h>
+#include "MemInfoHob.h"
+#include <Protocol\MemInfo\MemInfo.h>
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+#include <PerfTune.h>
+#include <Protocol\PerfTuneProtocol.h>
+#endif
+#endif
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 0
+#include <Protocol\Wdt\Wdt.h>
+#endif
+
+#include <Protocol\PchS3Support\PchS3Support.h>
+
+#if NB_ERROR_LOG_SUPPORT
+#include <Protocol\GenericElog.h>
+#endif
+
+#include <Protocol\ConsoleControl.h>
+#include <Protocol\SmBus.h>
+#include <AmiLoadCsmPolicy.h>
+
+#include <SaGlobalNvsArea\SaGlobalNvsArea.h>
+#include <Protocol\GlobalNvsArea\GlobalNvsArea.h>
+
+#ifndef EFI_SIGNATURE_16
+#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8))
+#endif
+
+#ifndef EFI_SIGNATURE_32
+#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#endif
+
+//----------------------------------------------------------------------------
+// Constant, Macro and Type Definition(s)
+//----------------------------------------------------------------------------
+// Constant Definition(s)
+
+#ifndef SMM_SUPPORT
+ #define SMM_SUPPORT 0
+#endif
+
+#define NB_TEMP_PCI_BUS 0x10
+
+// Macro Definition(s)
+
+// Type Definition(s)
+typedef struct {
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Fun;
+ VOID *Process;
+} DEVICES_AFTER_PCIIO;
+
+
+#define RC_EFI_ACPI_VARIABLE_GUID \
+ { \
+ 0xc020489e, 0x6db2, 0x4ef2, 0x9a, 0xa5, 0xca, 0x6, 0xfc, 0x11, 0xd3, 0x6a \
+ }
+
+#define EFI_PCI_ENUMERATION_COMPLETE_GUID \
+ { \
+ 0x30cfe3e7, 0x3de1, 0x4586, { 0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93 } \
+ }
+
+typedef struct {
+ ///
+ /// Acpi Related variables
+ ///
+ EFI_PHYSICAL_ADDRESS AcpiReservedMemoryBase;
+ UINT32 AcpiReservedMemorySize;
+ EFI_PHYSICAL_ADDRESS S3ReservedLowMemoryBase;
+ EFI_PHYSICAL_ADDRESS AcpiBootScriptTable;
+ EFI_PHYSICAL_ADDRESS RuntimeScriptTableBase;
+ EFI_PHYSICAL_ADDRESS AcpiFacsTable;
+ UINT64 SystemMemoryLength;
+ ACPI_CPU_DATA AcpiCpuData;
+ ///
+ /// VGA OPROM to support Video Re-POST for Linux S3
+ ///
+ EFI_PHYSICAL_ADDRESS VideoOpromAddress;
+ UINT32 VideoOpromSize;
+
+ ///
+ /// S3 Debug extension
+ ///
+ EFI_PHYSICAL_ADDRESS S3DebugBufferAddress;
+ EFI_PHYSICAL_ADDRESS S3ResumeNvsEntryPoint;
+} RC_ACPI_VARIABLE_SET;
+
+
+// Function Prototype(s)
+
+EFI_STATUS NBDXE_BoardInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN NB_SETUP_DATA *SetupData
+);
+
+VOID NbInitAfterDeviceInstall (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+VOID InitNbRegsBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+VOID InitRcAcpiVariableSet(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_STATUS InstallNbMemoryInfo (
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+VOID CreateNbAcpiComponent ( VOID );
+
+EFI_STATUS NbSmmInit (
+ IN EFI_EVENT Event,
+ IN VOID *Context);
+
+#ifdef CSM_OPRROM_POLICY_GUID
+VOID NbCheckOprom (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+#endif
+
+VOID NbSetupNvramUpdatedCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+VOID NbPciEnumerationCompleteProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+VOID NbExitPmAuthProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_STATUS InstallDxePlatformSaPolicy (VOID);
+
+EFI_STATUS
+RmrrUpdateCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_STATUS NBDXE_ShadowRam (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+// (P20121012A) >> Update XTU 4.0
+EFI_STATUS NbReportXmpInfo(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+typedef struct {
+ UINT32 tCK;
+ MrcFrequency DDRFreq;
+ UINT8 RefClkFlag; // 0 = invalid freq. 1 = valid only at 133 RefClk, 2 = valid only at 100 RefClk, 3 = valid at both.
+} NbTRangeTable;
+
+typedef struct {
+ MrcFrequency DDRFreq;
+ MrcTiming TimingData;
+} NbXmpProfileData;
+
+typedef struct {
+ NbXmpProfileData XmpProfileTiming[2];
+} XmpDimmData;
+
+//NbXmpProfileData XmpProfileTiming[2] = {0};
+//XmpDimmData XmpDimm[4] = {0};
+//XmpDimmData XmpChannel[2] = {0};
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+VOID NbXTUSetGACITable(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+DDDT_PRESENT_FLAG_HOB *gDddtPresentFlagHob = NULL;
+#endif
+#endif
+// (P20121012A) << Update XTU 4.0
+//----------------------------------------------------------------------------
+// Variable and External Declaration(s)
+//----------------------------------------------------------------------------
+// Variable Declaration(s)
+
+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo = NULL;
+AMI_S3_SAVE_PROTOCOL *gBootScript = NULL;
+EFI_EVENT gEvent;
+EFI_EVENT gEvtBootScript;
+VOID *gNBInitNotifyReg = NULL;
+VOID *gUpdateCsmProtocolNotifyReg = NULL;
+NB_SETUP_DATA *gNbSetupData = NULL;
+VOID *gCsmOpromReg = NULL;
+VOID *gNbSetupNvramUpdatedReg = NULL;
+VOID *gPciEnumerationCompleteProtocolReg = NULL;
+VOID *gNbExitPmAuthProtocolReg = NULL;
+VOID *gInterface = NULL;
+MEM_INFO_PROTOCOL gMemInfoHobProtocol;
+NB_PLATFORM_DATA NBPlatformData = {0};
+UINT32 gBClkFrequency = 0;
+BOOLEAN gHideIGFXdevice;
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+PERF_TUNE_ASL_PROTOCOL *gPerfTuneAslProtocol = NULL;
+#endif
+#endif
+MrcProfile MemoryProfile = 0;
+MrcTiming *NBMrcTimingData;
+
+
+// GUID Definition(s)
+
+EFI_GUID gEfiPciRootBridgeIoProtocolGuid = \
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+EFI_GUID gEfiPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+EFI_GUID gSetupNvramUpdatedGuid = AMITSE_NVRAM_UPDATE_GUID;
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+//EFI_GUID gMrcS3ResumeDataHobGuid = AMI_MRC_S3_RESUME_DATA_HOB_GUID;
+EFI_GUID gDxePlatformSaPolicyGuid = DXE_PLATFORM_SA_POLICY_GUID;
+EFI_GUID gMemInfoProtocolGuid = MEM_INFO_PROTOCOL_GUID;
+EFI_GUID gMemRestoreDataGuid = EFI_MEMORY_RESTORE_DATA_GUID;
+EFI_GUID gAmiNbPegGen3PresetSearchGuid = AMI_NB_PEG_GEN3_PRESET_SEARCH_GUID;
+EFI_GUID gMrcInfoHobGuid = AMI_MRC_INFO_HOB_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+EFI_GUID gAmiLoadCsmGuid = AMI_LOAD_CSM_GUID;
+EFI_GUID gConOutStartedCheckGuid = CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID;
+EFI_GUID gExitPmAuthProtocolGuid = EXIT_PM_AUTH_PROTOCOL_GUID;
+EFI_GUID gEfiSmbusProtocolGuid = EFI_SMBUS_HC_PROTOCOL_GUID;
+EFI_GUID gAmiNbPegInfoGuid = AMI_NB_PEG_INFO_GUID;
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+EFI_GUID gPerfTuneAslProtocolGuid = PERF_TUNE_ASL_PROTOCOL_GUID;
+EFI_GUID gAmiPerfTuneDataHobGuid = AMI_PERF_TUNE_DATA_HOB_GUID;
+EFI_GUID gAmiInternalFactoryTdcTdpHobGuid = AMI_INTERNAL_FACTORY_TDC_TDP_HOB_GUID;
+#endif
+#endif
+
+#ifdef CSM_OPRROM_POLICY_GUID
+EFI_GUID gCsmOpromPolicyGuid = CSM_OPRROM_POLICY_GUID;
+#endif
+
+#if NB_ERROR_LOG_SUPPORT
+EFI_GUID gElogProtocolGuid = EFI_SM_ELOG_PROTOCOL_GUID;
+#endif
+
+extern EFI_GUID gSaDataHobGuid;
+extern EFI_GUID gEfiSmmAccessProtocolGuid;
+
+#if (CORE_VERSION >= 4600)
+//----------------------------------------------------------------------------
+//THIS TABLE MUST BE FILLED WITH RESOURCE REGIONS DECODED BY THE NB FOR ITSELF
+//!!! NOTE :Use Attributes field == -1 to mark an IO Space Resource.
+// you must provide valid attributes for Memory Mapped IO regions.
+//----------------------------------------------------------------------------
+
+CSP_RES_ITEM gNbCspResTable[] = {
+//----------------------------------------------------------------------------
+// UINT64 ResBase UINTN ResLength GCD_MEMORY_TYPE ResType UINT64 Attributes
+//----------------------------------------------------------------------------
+//Add PCI Express region
+{ PCIEX_BASE_ADDRESS, PCIEX_LENGTH,EfiGcdMemoryTypeMemoryMappedIo , \
+ (EFI_MEMORY_UC|EFI_MEMORY_RUNTIME)},
+//Local APICs dedicated Space
+{ LOCAL_APIC_BASE , 0x00001000 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ (EFI_MEMORY_UC|EFI_MEMORY_RUNTIME)},
+//Egress Port Base Address Region
+{ NB_EP_BASE_ADDRESS, 4*1024 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ EFI_MEMORY_UC},
+//MCH Memory Mapped Base Address Region
+{ NB_MCH_BASE_ADDRESS, 16*1024 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ EFI_MEMORY_UC},
+//Root Complex Base Address Region
+{ NB_DMI_BASE_ADDRESS, 4*1024 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ EFI_MEMORY_UC},
+//Edram Base Address Region
+{ NB_DERAM_BASE_ADDRESS, 16*1024 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ EFI_MEMORY_UC},
+//GDXC Base Address Region
+{ NB_GDXC_BASE_ADDRESS, 4*1024 ,EfiGcdMemoryTypeMemoryMappedIo , \
+ EFI_MEMORY_UC},
+//Here Goes Reserved IO Space
+//IO Used for PCI Config access
+{ NB_PCICFG_SPACE_INDEX_REG , 8 ,EfiGcdIoTypeIo , -1 },
+
+};
+
+UINTN gNbCspResCount = sizeof(gNbCspResTable) / sizeof(CSP_RES_ITEM);
+
+#endif
+
+
+DEVICES_AFTER_PCIIO gDevicesTable[] = {
+ { PCIEBRN_BUS, PCIEBRN_DEV, PCIEBRN_FUN, NULL },
+ { PCIEBRN_BUS, PCIEBRN_DEV, PCIEBRN_FUN1, NULL },
+ { PCIEBRN_BUS, PCIEBRN_DEV, PCIEBRN_FUN2, NULL },
+ { 0xFF, 0xFF, 0xFF, NULL }
+};
+
+UINTN gEventCount = sizeof(gDevicesTable) / sizeof(DEVICES_AFTER_PCIIO);
+
+PCIE_ASPM_DEV_INFO mPcieAspmDevsOverride[] = {
+ ///
+ /// Tekoa w/o iAMT
+ ///
+ {0x8086, 0x108b, 0xff, 2, 2},
+ ///
+ /// Tekoa A2
+ ///
+ {0x8086, 0x108c, 0x00, 0, 0},
+ ///
+ /// Tekoa others
+ ///
+ {0x8086, 0x108c, 0xff, 2, 2},
+ ///
+ /// Vidalia
+ ///
+ {0x8086, 0x109a, 0xff, 2, 2},
+ ///
+ /// 3945ABG
+ ///
+ {0x8086, 0x4222, 0xff, 2, 3},
+ ///
+ /// 3945ABG
+ ///
+ {0x8086, 0x4227, 0xff, 2, 3},
+ ///
+ /// 3945ABG
+ ///
+ {0x8086, 0x4228, 0xff, 2, 3},
+ ///
+ /// End of table
+ ///
+ {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}
+};
+
+PCIE_LTR_DEV_INFO mPcieLtrDevsOverride[] = {
+ ///
+ /// Place holder for PCIe devices with correct LTR requirements
+ ///
+ ///
+ /// End of table
+ ///
+ {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}
+};
+// Protocol Definition(s)
+
+// External Declaration(s)
+
+// Function Definition(s)
+
+//----------------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NBDXE_Init
+//
+// Description: This function is the entry point for this DXE. This function
+// initializes the chipset NB before PCI Bus enumeration.
+//
+// Input: ImageHandle - Image handle
+// SystemTable - Pointer to the system table
+//
+// Output: Return Status based on errors that occurred while waiting for
+// time to expire.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS NBDXE_Init (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ CPUINFO_HOB *CpuInfoHob = NULL;
+ EFI_GUID AmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ UINT8 i = 0;
+ UINTN VariableSize;
+ EFI_EVENT Event;
+ VOID *HobData;
+ VOID *VariableData;
+ UINTN S3DataOffset;
+ UINT16 McDeviceId;
+ UINT16 LpcDeviceId;
+ VOID *Protocol = NULL;
+ VOID *NotifyReg = NULL;
+ UINT32 Attributes = 0; // [ EIP167027 ]
+
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ PROGRESS_CODE (DXE_NB_INIT);
+
+ Status = pBS->LocateProtocol( &gEfiPciRootBridgeIoProtocolGuid, \
+ NULL, \
+ &gPciRootBridgeIo );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol( AMI_S3_SAVE_PROTOCOL_GUID, \
+ NULL, \
+ &gBootScript );
+ ASSERT_EFI_ERROR(Status);
+
+ VariableData = NULL;
+ S3DataOffset = 0;
+
+ HobData = (EFI_HOB_GENERIC_HEADER *) GetEfiConfigurationTable (pST, &gHobListGuid);
+ if (!HobData)ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+
+ Status = FindNextHobByGuid (&gSaDataHobGuid, &HobData);
+ if (Status == EFI_SUCCESS) {
+
+ // Use the hob to save PegGen3PresetSearch Configuration Data
+ S3DataOffset = (UINTN) &(((SA_DATA_HOB *) 0)->PegData);
+
+ //Status = pRS->SetVariable ( // [ EIP167027 ]
+ // L"PegGen3PresetSearchData",
+ // &gAmiNbPegGen3PresetSearchGuid,
+ // (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+ // sizeof(SA_PEG_DATA),
+ // (UINT8 *) HobData + S3DataOffset
+ // );
+ Status = pRS->SetVariable (
+ L"PegGen3PresetSearchData",
+ &gAmiNbPegGen3PresetSearchGuid,
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+ sizeof(SA_PEG_DATA),
+ (UINT8 *) HobData + S3DataOffset
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ HobData = (EFI_HOB_GENERIC_HEADER *) GetEfiConfigurationTable (pST, &gHobListGuid);
+ if (!HobData)ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+
+ Status = FindNextHobByGuid (&gMemRestoreDataGuid, &HobData);
+ if (Status == EFI_SUCCESS) {
+
+ // Use the hob to save Memory Configuration Data
+ S3DataOffset = (UINTN) &(((HOB_SAVE_MEMORY_DATA *) 0)->MrcData.SysSave);
+
+ //Status = pRS->SetVariable ( // [ EIP167027 ]
+ // L"MrcS3Resume",
+ // &gMemRestoreDataGuid,
+ // (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+ // sizeof(SysSave),
+ // (UINT8 *) HobData + S3DataOffset
+ // );
+ Status = pRS->SetVariable (
+ L"MrcS3Resume",
+ &gMemRestoreDataGuid,
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+ sizeof(SysSave),
+ (UINT8 *) HobData + S3DataOffset
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ // Set DRAM Initialization Bit. // [ EIP161790 ]
+ if ((READ_PCI8_SB(SB_REG_GEN_PMCON_2) & BIT07) == 0)
+ {
+ SET_PCI8_SB(SB_REG_GEN_PMCON_2, BIT07); // 0xA2
+ }
+
+ // Read the NB Setup Data
+ VariableSize = sizeof (NB_SETUP_DATA);
+ Status = pBS->AllocatePool( EfiBootServicesData, \
+ VariableSize, \
+ &gNbSetupData );
+ ASSERT_EFI_ERROR(Status);
+
+ GetNbSetupData( pRS, gNbSetupData, FALSE );
+
+ // Read the NB Platform Data
+ VariableSize = sizeof (NB_PLATFORM_DATA);
+ //Status = pRS->GetVariable ( // [ EIP167027 ]
+ // L"NBPlatformData",
+ // &gSetupGuid,
+ // NULL,
+ // &VariableSize,
+ // &NBPlatformData
+ // );
+ Status = pRS->GetVariable (
+ L"NBPlatformData",
+ &gSetupGuid,
+ &Attributes,
+ &VariableSize,
+ &NBPlatformData
+ );
+ if (EFI_ERROR(Status))
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ // Check CPU is Support IGFX.
+ NBPlatformData.IGFXCapability = (READ_PCI32_NB (R_SA_MC_CAPID0_A_OFFSET) & BIT11) ? FALSE : TRUE;
+
+ NBPlatformData.PegAvailable = (GetPchSeries() == PchLp) ? FALSE : TRUE;
+ // Check IGFX is Available.
+ NBPlatformData.IGFXAvailable = (READ_PCI32_IGD (R_SA_IGD_VID) != 0xFFFFFFFF) ? TRUE : FALSE;
+
+#if defined NB_IGFX_FORCE_DISABLE_SUPPORT && NB_IGFX_FORCE_DISABLE_SUPPORT == 1
+ if(gNbSetupData->IGfxForceDisable == 1)
+ NBPlatformData.IGFXAvailable = 0;
+#endif // NB_IGFX_FORCE_DISABLE_SUPPORT
+
+ // Read MC device ID
+ McDeviceId = READ_PCI16_NB(R_SA_MC_DEVICE_ID);
+
+ // Read PCH device ID
+ LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID);
+
+ NBPlatformData.PresentCPU = 2;
+
+ // Mobile - 0; Desktop - 2; UpServer - 3; FlavorWorkStation - 4;
+ if(IS_SA_DEVICE_ID_MOBILE(McDeviceId)) {
+ NBPlatformData.UserBoard = FlavorMobile;
+ } else if(IS_SA_DEVICE_ID_DESKTOP (McDeviceId) | IS_SA_DEVICE_ID_SERVER(McDeviceId)) {
+ if(IS_PCH_LPT_LPC_DEVICE_ID_WS (LpcDeviceId)) {
+ NBPlatformData.UserBoard = FlavorWorkStation;
+ } else if(IS_PCH_LPT_LPC_DEVICE_ID_SERVER (LpcDeviceId)) {
+ NBPlatformData.UserBoard = FlavorUpServer;
+ } else {
+ NBPlatformData.UserBoard = FlavorDesktop;
+ }
+ } else {
+ NBPlatformData.UserBoard = FlavorDesktop;
+ }
+
+ Status = NBDXE_BoardInit(ImageHandle, SystemTable, gNbSetupData);
+
+ //
+ // Detect if CSM is exist. If it's not, the shawdow ram can be set.
+ //
+ Status = pBS->LocateProtocol( &gAmiLoadCsmGuid, \
+ NULL, \
+ &gInterface );
+ if(EFI_ERROR(Status))
+ {
+ Status = NBDXE_ShadowRam(ImageHandle, SystemTable);
+ }
+
+#if PciHostBridge_SUPPORT
+ CreateNbAcpiComponent();
+#endif
+
+ Status = RegisterProtocolCallback( &gEfiPciIoProtocolGuid, \
+ NbInitAfterDeviceInstall, \
+ NULL, &gEvent, &gNBInitNotifyReg );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = RegisterProtocolCallback( &gConOutStartedCheckGuid,
+ NbPciEnumerationCompleteProtocolCallback,
+ NULL, &gEvent, &gPciEnumerationCompleteProtocolReg );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = RegisterProtocolCallback( &gExitPmAuthProtocolGuid, \
+ NbExitPmAuthProtocolCallback, \
+ NULL, \
+ &Event, \
+ &gNbExitPmAuthProtocolReg );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateReadyToBootEvent( TPL_NOTIFY, InitNbRegsBeforeBoot, \
+ NULL, &gEvent );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateReadyToBootEvent(
+ (TPL_CALLBACK - 1),
+ InitRcAcpiVariableSet,
+ NULL,
+ &Event);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = InstallDxePlatformSaPolicy ();
+ ASSERT_EFI_ERROR(Status);
+
+ Status = InstallNbMemoryInfo ( SystemTable );
+ ASSERT_EFI_ERROR(Status);
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+ if(!EFI_ERROR(Status))
+ {
+ EFI_EVENT Event;
+ VOID *Reg;
+
+ Status = pBS->LocateProtocol (&gPerfTuneAslProtocolGuid, NULL, &gPerfTuneAslProtocol);
+ if(Status == EFI_SUCCESS)
+ {
+ NbXTUSetGACITable(NULL,NULL);
+ }else{
+ //Create event for Notify XTU setting
+ Status = RegisterProtocolCallback(
+ &gPerfTuneAslProtocolGuid,
+ NbXTUSetGACITable,
+ NULL, &Event, &Reg);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+#endif
+#endif
+
+#ifdef CSM_OPRROM_POLICY_GUID
+ Status = RegisterProtocolCallback( &gCsmOpromPolicyGuid, \
+ NbCheckOprom, \
+ NULL, \
+ &Event, \
+ &gCsmOpromReg );
+
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ Status = RegisterProtocolCallback( &gSetupNvramUpdatedGuid,
+ NbSetupNvramUpdatedCallback,
+ NULL,
+ &Event,
+ &gNbSetupNvramUpdatedReg );
+
+#if (CORE_VERSION >= 4600)
+ Status = LibAllocCspResource( gNbCspResTable, \
+ gNbCspResCount, \
+ ImageHandle, \
+ SystemTable );
+#endif
+
+#if SMM_SUPPORT
+ Status = pBS->LocateProtocol(&gEfiSmmAccessProtocolGuid, NULL, &Protocol);
+ if (EFI_ERROR(Status))
+ {
+ Status = RegisterProtocolCallback(
+ &gEfiSmmAccessProtocolGuid,
+ NbSmmInit,
+ NULL,
+ &Event,
+ &NotifyReg);
+ ASSERT_EFI_ERROR(Status);
+ }
+ else
+ {
+ Status = NbSmmInit(NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+#ifndef OVERRIDE_FOR_SET_MAX_PAYLOAD
+ {
+ UINTN PegAddress;
+ UINT8 PegBus;
+ UINT8 PegDev;
+ UINT8 PegFun;
+ UINTN i;
+
+ for ( i = 0; gDevicesTable[i].Bus != 0xff; i++)
+ {
+ PegBus = gDevicesTable[i].Bus;
+ PegDev = gDevicesTable[i].Dev;
+ PegFun = gDevicesTable[i].Fun;
+
+ if (READ_PCI32 (PegBus, PegDev, PegFun, PCI_VID) == 0xFFFFFFFF) continue;
+
+ // Haswell EDS 2.19.35
+ // Default indicates 256B max supported payload for
+ // Transaction Layer Packets (TLP) for x16 PEG only.
+ // x8 and x4 PEG are limited to 128B support.
+ PegAddress = NB_PCIE_CFG_ADDRESS(PegBus, PegDev, PegFun, 0);
+ if (((READ_MMIO16 (PegAddress + R_SA_PEG_LSTS_OFFSET) & 0x01F0) >> 4) != 0x10)
+ RESET_MMIO8 (PegAddress + R_SA_PEG_DCAP_OFFSET, BIT0 + BIT1 + BIT2);
+ }
+ }
+#endif // OVERRIDE_FOR_SET_MAX_PAYLOAD
+
+ // Save SETUP variables.
+ //Status = pRS->SetVariable ( // [ EIP167027 ]
+ // L"NBPlatformData",
+ // &gSetupGuid,
+ // EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ // sizeof (NB_PLATFORM_DATA),
+ // &NBPlatformData
+ // );
+ Status = pRS->SetVariable (
+ L"NBPlatformData",
+ &gSetupGuid,
+ Attributes,
+ sizeof (NB_PLATFORM_DATA),
+ &NBPlatformData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitNbRegsBeforeBoot
+//
+// Description: This function can initialize any NB registers before DXE
+// stage exiting.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitNbRegsBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+//#if defined Remove_SaSsdt_Data_To_Dsdt && Remove_SaSsdt_Data_To_Dsdt
+ UINT32 Index;
+ EFI_ACPI_SUPPORT_PROTOCOL *As;
+ FACP_20 *Table = NULL;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINTN Handle;
+ ACPI_HDR *DsdtPtr = NULL;
+ EFI_STATUS Status;
+ ASL_OBJ_INFO ObjInfo;
+ UINT16 ASLDeviceOP;
+ UINT8 ASLDeviceOPLength;
+ UINT8 *ptr;
+ UINT8 i;
+ UINT8 j;
+#if defined Remove_SaSsdt_Data_To_Dsdt && Remove_SaSsdt_Data_To_Dsdt
+ UINT8 *GlobalSaptr, *SAptr;
+ SYSTEM_AGENT_GLOBAL_NVS_AREA_PROTOCOL *SaGlobalNvsArea, *GlobalSaNvsArea;
+ EFI_GUID gSaGlobalNvsAreaProtocolGuid = SYSTEM_AGENT_GLOBAL_NVS_AREA_PROTOCOL_GUID;
+ EFI_GUID gEfiGlobalSaNvsAreaProtocolGuid = EFI_GLOBAL_SANVS_AREA_PROTOCOL_GUID;
+#endif
+ UINT8 *ptr1;
+ UINT16 PXSXASLDeviceOP;
+ UINT8 PXSXASLDeviceOPLength;
+ UINT8 HPMEASLMethodOPLength;
+ UINT16 HPMEASLMethodOPLength16;
+ UINT16 ASLDeviceOPLength16;
+ UINT32 *Signature;
+
+#if NB_ERROR_LOG_SUPPORT == 1
+#if NB_ECC_ERROR_LOG_SUPPORT == 1
+
+ if(gNbSetupData->EccSupport) {
+
+ if (((READ_MEM32_MCH(0x5004) & (BIT24 | BIT25)) != 0) ||
+ ((READ_MEM32_MCH(0x5008) & (BIT24 | BIT25)) != 0))
+ {
+ RW_MEM32_MCH(0x40B8, 0, (BIT14 | BIT16 | BIT17));
+ RW_MEM32_MCH(0x44B8, 0, (BIT14 | BIT16 | BIT17));
+
+ // Disable Error and SCI Commands
+ RW_PCI16_NB(0xCA, 0, (BIT00 | BIT01));
+ RW_PCI16_NB(0xCE, 0, (BIT00 | BIT01));
+
+ // Enable SMI Command
+ //SET_PCI8_NB(0xC8, BIT00);
+ RW_PCI16_NB(0xCC, (BIT00 | BIT01), 0);
+ }
+
+ }
+
+#endif
+#endif
+
+#if defined Remove_SaSsdt_Data_To_Dsdt && Remove_SaSsdt_Data_To_Dsdt
+ ///
+ /// Locate the SA SSDT NVS Protocol.
+ ///
+ Status = pBS->LocateProtocol (
+ &gSaGlobalNvsAreaProtocolGuid,
+ NULL,
+ &SaGlobalNvsArea
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Locate the SA Global NVS Protocol.
+ //
+ Status = pBS->LocateProtocol (
+ &gEfiGlobalSaNvsAreaProtocolGuid,
+ NULL,
+ &GlobalSaNvsArea
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Update SA SSDT GNVS data to Global DSDT SA GNVS
+ SAptr = (UINT8*)(SaGlobalNvsArea->Area);
+ GlobalSaptr = (UINT8*)(GlobalSaNvsArea->Area);
+ TRACE((TRACE_ALWAYS, "Global SA GNVS PTR=0x%08X, SA SSDT GNVS PTR=0x%08X\n", GlobalSaptr, SAptr));
+
+ for (Index = 0; Index < sizeof (SYSTEM_AGENT_GLOBAL_NVS_AREA); Index++) {
+ *(UINT8*)(GlobalSaptr + Index) = (UINT8)*(UINT8*)(SAptr + Index);
+ }
+
+#endif
+
+ // It must be only one instance of such protocol
+ Status = pBS->LocateProtocol(&gEfiAcpiSupportGuid, NULL, &As);
+ if(EFI_ERROR(Status)) {
+ TRACE((-1, "ACPI Support Protocol is not ready for NB components\n"));
+ return;
+ }
+ TRACE((-1,"NB Locate Protocol(ACPISupport)- %r Success\n", Status));
+
+ // Find DSDT ACPI Table
+ for (Index = 0; Index < ACPI_RSDT_TABLE_NUM; Index++) {
+ Status = As->GetAcpiTable(As, Index, &Table, &Version, &Handle);
+ if (EFI_ERROR(Status)) break;//no more tables left
+ if ((Table->Header.Signature == FACP_SIG) && (DsdtPtr == NULL)) {
+ DsdtPtr = (ACPI_HDR*)Table->DSDT;
+
+ TRACE((-1, "NBDxe: Found DSDT Table at 0x%08X\n", DsdtPtr));
+
+
+ break;
+ }
+ }
+
+ Status = GetAslObj( (UINT8*)(DsdtPtr + 1), DsdtPtr->Length - sizeof(ACPI_HDR) - 1,
+ "P0P2", otDevice, &ObjInfo );
+
+ if (!EFI_ERROR(Status))
+ {
+ ptr = (UINT8*)(ObjInfo.DataStart) - 7;
+ (UINT16)ASLDeviceOP = *(UINT32*)(ptr);
+ (UINT8)ASLDeviceOPLength = *(UINT32*)(ptr + 2);
+
+ TRACE((TRACE_ALWAYS, "SA POP2 Device PTR=0x%08X, ASLDeviceOP=0x%X, ASLDeviceOPLength=0x%X\n", ptr, (UINT16)ASLDeviceOP, (UINT8)ASLDeviceOPLength));
+ if (ASLDeviceOP == 0x825B) // Is DeviceOP ?
+ {
+ for ( i = 0; i < ASLDeviceOPLength + 2; i++) {
+ *(UINT8*)(ptr + i) = 0;
+ }
+ }
+ }
+
+ Status = GetAslObj( (UINT8*)(DsdtPtr + 1), DsdtPtr->Length - sizeof(ACPI_HDR) - 1,
+ "P0PA", otDevice, &ObjInfo );
+
+ if (!EFI_ERROR(Status))
+ {
+ ptr = (UINT8*)(ObjInfo.DataStart) - 7;
+ (UINT16)ASLDeviceOP = *(UINT32*)(ptr);
+ (UINT8)ASLDeviceOPLength = *(UINT32*)(ptr + 2);
+
+ TRACE((TRACE_ALWAYS, "SA POPA Device PTR=0x%08X, ASLDeviceOP=0x%X, ASLDeviceOPLength=0x%X\n", ptr, (UINT16)ASLDeviceOP, (UINT8)ASLDeviceOPLength));
+ if (ASLDeviceOP == 0x825B) // Is ASL DeviceOP ?
+ {
+ for ( i = 0; i < ASLDeviceOPLength + 2; i++) {
+ *(UINT8*)(ptr + i) = 0;
+ }
+ }
+ }
+
+ Status = GetAslObj( (UINT8*)(DsdtPtr + 1), DsdtPtr->Length - sizeof(ACPI_HDR) - 1,
+ "P0PB", otDevice, &ObjInfo );
+
+ if (!EFI_ERROR(Status))
+ {
+ ptr = (UINT8*)(ObjInfo.DataStart) - 7;
+ (UINT16)ASLDeviceOP = *(UINT32*)(ptr);
+ (UINT8)ASLDeviceOPLength = *(UINT32*)(ptr + 2);
+
+ TRACE((TRACE_ALWAYS, "SA POPB Device PTR=0x%08X, ASLDeviceOP=0x%X, ASLDeviceOPLength=0x%X\n", ptr, (UINT16)ASLDeviceOP, (UINT8)ASLDeviceOPLength));
+ if (ASLDeviceOP == 0x825B) // Is ASL DeviceOP ?
+ {
+ for ( i = 0; i < ASLDeviceOPLength + 2; i++) {
+ *(UINT8*)(ptr + i) = 0;
+ }
+ }
+ }
+
+ if (GetPchSeries() == PchLp) {
+ if(gNbSetupData->PrimaryDisplay == 4) {
+
+ Status = GetAslObj( (UINT8*)(DsdtPtr + 1), DsdtPtr->Length - sizeof(ACPI_HDR) - 1,
+ "RP05", otDevice, &ObjInfo );
+ if (!EFI_ERROR(Status))
+ {
+ ptr = (UINT8*)(ObjInfo.DataStart) - 8;
+ (UINT16)ASLDeviceOP = *(UINT32*)(ptr);
+ (UINT8)ASLDeviceOPLength = *(UINT32*)(ptr + 2);
+ ASLDeviceOPLength16 = (ASLDeviceOPLength & 0x0F);
+ (UINT8)ASLDeviceOPLength = *(UINT32*)(ptr + 3);
+ ASLDeviceOPLength16 = (ASLDeviceOPLength << 4) | ASLDeviceOPLength16;
+
+ TRACE((TRACE_ALWAYS, "RP05 Device PTR=0x%08X, ASLDeviceOP=0x%X, ASLDeviceOPLength=0x%X\n", ptr, (UINT16)ASLDeviceOP, (UINT16)ASLDeviceOPLength16));
+ if (ASLDeviceOP == 0x825B) // Is ASL DeviceOP ?
+ {
+ Status = GetAslObj( (UINT8*)(ptr + 1), ASLDeviceOPLength16 - sizeof(ACPI_HDR) - 1,
+ "_STA", otMethod, &ObjInfo );
+ if (!EFI_ERROR(Status))
+ {
+ ptr1 = (UINT8*)(ObjInfo.DataStart) - 5;
+ TRACE((TRACE_ALWAYS, "_STA Method PTR=0x%08X\n", ptr1));
+ *(UINT8*)ptr1 = 'X';
+ }
+
+ //remove device PXSX
+ Status = GetAslObj( (UINT8*)(ptr + 1), ASLDeviceOPLength16 - sizeof(ACPI_HDR) - 1,
+ "PXSX", otDevice, &ObjInfo );
+ if (!EFI_ERROR(Status))
+ {
+
+ ptr1 = (UINT8*)(ObjInfo.DataStart) - 7;
+ (UINT16)PXSXASLDeviceOP = *(UINT32*)(ptr1);
+ (UINT8)PXSXASLDeviceOPLength = *(UINT32*)(ptr1 + 2);
+ TRACE((TRACE_ALWAYS, "PXSX Device PTR=0x%08X, ASLDeviceOP=0x%X, ASLDeviceOPLength=0x%X\n", ptr1, (UINT16)PXSXASLDeviceOP, (UINT8)PXSXASLDeviceOPLength));
+
+ if (PXSXASLDeviceOP == 0x825B) // Is ASL DeviceOP ?
+ {
+ for ( i = 0; i < PXSXASLDeviceOPLength + 2; i++) {
+ *(UINT8*)(ptr1 + i) = 0;
+ }
+ }
+ }
+
+ Status = GetAslObj( (UINT8*)(ptr + 1), ASLDeviceOPLength16 - sizeof(ACPI_HDR) - 1,
+ "HPME", otMethod, &ObjInfo );
+ if (!EFI_ERROR(Status))
+ {
+ ptr1 = (UINT8*)(ObjInfo.DataStart) - 8;
+ (UINT8)HPMEASLMethodOPLength = *(UINT32*)(ptr1 + 1);
+ HPMEASLMethodOPLength16 = (HPMEASLMethodOPLength & 0x0F);
+ (UINT8)HPMEASLMethodOPLength = *(UINT32*)(ptr1 + 2);
+ HPMEASLMethodOPLength16 = (HPMEASLMethodOPLength << 4) | HPMEASLMethodOPLength16;
+ TRACE((TRACE_ALWAYS, "HPME Method PTR=0x%08X,HPMEASLMethodOPLength16=0x%X\n", ptr1,(UINT16)HPMEASLMethodOPLength16));
+
+ for ( i = 0; i < HPMEASLMethodOPLength16 ; i++) {
+ Signature = (UINT32 *) (ptr1 + i);
+ //TRACE((TRACE_ALWAYS, "PXSX Notify PTR%d = 0x%08X\n", i,Signature));
+ if(*Signature == EFI_SIGNATURE_32 ('P', 'X', 'S', 'X')){
+ TRACE((TRACE_ALWAYS, "PXSX Notify PTR = 0x%08X\n", Signature));
+ for ( j = 0; j < 7 ; j++) {
+ *(UINT8*)(ptr1 + i + j -1) = 0;
+ }
+ }
+ }
+ }
+
+
+ }
+ }
+ }// if(gNbSetupData->PrimaryDisplay == 4) {
+ }//if (GetPchSeries() == PchLp)
+
+ //Kill the Event
+ pBS->CloseEvent(Event);
+
+}
+
+VOID InitRcAcpiVariableSet(
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+ EFI_GUID mEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+ EFI_GUID mRcEfiAcpiVariableGuid = RC_EFI_ACPI_VARIABLE_GUID;
+ ACPI_VARIABLE_SET *pAcpiVariableSet = NULL;
+ RC_ACPI_VARIABLE_SET *pRcAcpiVariableSet = NULL;
+ UINTN VariableSize = sizeof(UINT32);
+ UINT32 Attributes;
+
+ //Status = pRS->GetVariable ( // [ EIP167027 ]
+ // L"AcpiGlobalVariable",
+ // &mEfiAcpiVariableGuid,
+ // NULL,
+ // &VariableSize,
+ // &pAcpiVariableSet
+ // );
+ Status = pRS->GetVariable (
+ L"AcpiGlobalVariable",
+ &mEfiAcpiVariableGuid,
+ &Attributes,
+ &VariableSize,
+ &pAcpiVariableSet
+ );
+ if (EFI_ERROR(Status))
+ {
+ return;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiACPIMemoryNVS,
+ sizeof(RC_ACPI_VARIABLE_SET),
+ &pRcAcpiVariableSet
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SetMem(pRcAcpiVariableSet, sizeof(RC_ACPI_VARIABLE_SET), 0);
+
+ pRcAcpiVariableSet->AcpiReservedMemoryBase = pAcpiVariableSet->AcpiReservedMemoryBase;
+ pRcAcpiVariableSet->AcpiReservedMemorySize = pAcpiVariableSet->AcpiReservedMemorySize;
+ pRcAcpiVariableSet->S3ReservedLowMemoryBase = pAcpiVariableSet->S3ReservedLowMemoryBase;
+ pRcAcpiVariableSet->AcpiBootScriptTable = pAcpiVariableSet->AcpiBootScriptTable;
+ pRcAcpiVariableSet->RuntimeScriptTableBase = pAcpiVariableSet->RuntimeScriptTableBase;
+ pRcAcpiVariableSet->AcpiFacsTable = pAcpiVariableSet->AcpiFacsTable[0];
+ pRcAcpiVariableSet->SystemMemoryLength = pAcpiVariableSet->SystemMemoryLength;
+ pRcAcpiVariableSet->AcpiCpuData = pAcpiVariableSet->AcpiCpuData;
+
+ //Status = pRS->SetVariable( // [ EIP167027 ]
+ // L"AcpiGlobalVariable",
+ // &mRcEfiAcpiVariableGuid,
+ // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ // sizeof(UINT64),
+ // &pRcAcpiVariableSet
+ // );
+ Status = pRS->SetVariable(
+ L"AcpiGlobalVariable",
+ &mRcEfiAcpiVariableGuid,
+ Attributes,
+ sizeof(UINT64),
+ &pRcAcpiVariableSet
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //Kill the Event
+ Status = pBS->CloseEvent(Event);
+ ASSERT_EFI_ERROR(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetExtCapStrucAddr
+//
+// Description: This routine is called to get the 16-bit offset of a
+// structure which can be located using the PCI Extended
+// Capabilities Pointer mechanism.
+//
+// Input: Bus - The PCI bus number of the PCI device.
+// Dev - The PCI device number of the PCI device.
+// Fun - The PCI function number of the PCI device.
+// FindCapNo - The Extended Capability ID to be found.
+// CapPtr16 - The offset address of desired structure
+//
+// Output: EFI_STATUS
+// EFI_NOT_FOUND - The desired structure is not found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetExtCapStrucAddr (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Fun,
+ IN UINT16 FindCapNo,
+ OUT UINT16 *CapPtr16 )
+{
+ UINT32 Buffer32;
+
+ *CapPtr16 = 0x100;
+
+ Buffer32 = READ_PCI32(Bus, Dev, Fun, *CapPtr16);
+ while (Buffer32 != 0xffffffff) {
+ if ((UINT16)Buffer32 == FindCapNo) return EFI_SUCCESS;
+ *CapPtr16 = (UINT16)((Buffer32 >> 20) & 0xfffc);
+ if (*CapPtr16 == 0) break;
+ Buffer32 = READ_PCI32(Bus, Dev, Fun, *CapPtr16);
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetLegCapStrucAddr
+//
+// Description: This routine is called to get the 16-bit offset of a
+// structure which can be located using the PCI Legacy
+// Capabilities Pointer mechanism.
+//
+// Input: Bus - The PCI bus number of the PCI device.
+// Dev - The PCI device number of the PCI device.
+// Fun - The PCI function number of the PCI device.
+// FindCapNo - The Legacy Capability ID to be found.
+// CapPtr16 - The offset address of desired structure
+//
+// Output: EFI_STATUS
+// EFI_NOT_FOUND - The desired structure is not found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetLegCapStrucAddr (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Fun,
+ IN UINT8 FindCapNo,
+ OUT UINT16 *CapPtr16 )
+{
+ UINT8 Buffer8;
+
+ if (READ_PCI32(Bus, Dev, Fun, PCI_VID) != 0xffffffff) {
+ if (READ_PCI16(Bus, Dev, Fun, 6) & 0x10) {
+ *CapPtr16 = ((READ_PCI8(Bus, Dev, Fun, 14) & 0x7f) == 2) ? \
+ 0x14:0x34;
+ *CapPtr16 = (UINT16)READ_PCI8(Bus, Dev, Fun, *CapPtr16);
+ if (*CapPtr16 == 0) return EFI_NOT_FOUND;
+ Buffer8 = READ_PCI8(Bus, Dev, Fun, *CapPtr16);
+ while (Buffer8 != 0) {
+ if (Buffer8 == FindCapNo) return EFI_SUCCESS;
+ Buffer8 = (UINT8)(*CapPtr16) + 1;
+ *CapPtr16 = (UINT16)(READ_PCI8(Bus, Dev, Fun, Buffer8));
+ if (*CapPtr16 == 0) break;
+ Buffer8 = READ_PCI8(Bus, Dev, Fun, *CapPtr16);
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FindPciGraphicAdapter
+//
+// Description: This routine tries to find any PCI graphic adapter on the
+// PCI bus.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+// EFI_NOT_FOUND - No PCI Graphic Adapter to be found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FindPciGraphicAdapter (VOID)
+{
+ UINT8 StartBus;
+ UINT8 EndBus;
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Fun;
+ UINT8 EndFun;
+ UINT8 Buffer8;
+ UINT32 Vid32;
+
+ StartBus = READ_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, PCIBR_REG_SBUSN);
+ EndBus = READ_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, PCIBR_REG_SUBUSN);
+
+ for (Bus = StartBus; Bus <= EndBus; Bus++) {
+ for (Dev = 0; Dev <= PCI_MAX_DEVICE; Dev++) {
+ Vid32 = READ_PCI32(Bus, Dev, 0, PCI_VID);
+ if (Vid32 != 0xffffffff) {
+ Buffer8 = READ_PCI8(Bus, Dev, 0, PCI_HDR);
+ EndFun = (Buffer8 & 0x80) ? 8 : 1;
+ for (Fun = 0; Fun < EndFun; Fun++) {
+ Vid32 = READ_PCI32(Bus, Dev, Fun, PCI_VID);
+ if (Vid32 != 0xffffffff) {
+ Buffer8=READ_PCI8(Bus, Dev, Fun, PCI_BCC);
+ if (Buffer8 == 3) return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+#if NB_PCIE_ERROR_LOG_SUPPORT
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbEnablePciDevErr
+//
+// Description: Enable the error register of PCI-Express Device.
+//
+// Input: IN UINT64 Address - PCIE devices Address
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NbEnablePciDevErr(
+ IN UINT64 Address
+)
+{
+ UINT32 DevBaseAddr = (UINT32)Address;
+ UINT8 CapPtr;
+
+ // Clear Error Status
+ WRITE_MEM8_S3(gBootScript, DevBaseAddr + 0x07, 0xff);//(BIT0 | BIT1 | BIT2 | BIT3));
+
+ CapPtr = NbFindCapPtr(DevBaseAddr, 0x10);
+ if(CapPtr != 0)
+ {
+ // Clear Device Error Status
+ SET_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x0A, (BIT0 | BIT1 | BIT2));
+ // Enable the error bits of Device Control
+ SET_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x08, (BIT0 | BIT1 | BIT2));
+ }
+
+ // Root?
+// if ((READ_MEM8(DevBaseAddr + CapPtr + 0x02) & 0xF0) == 0x40)
+ // if device is bridge
+ if (READ_MEM16(DevBaseAddr + 0x0A) == 0x0604)
+ {
+ WRITE_MEM8_S3(gBootScript, DevBaseAddr + 0x1F, 0xff);//(BIT0 | BIT1 | BIT2 | BIT3));
+ if(CapPtr != 0)
+ SET_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x1C, (BIT0 | BIT1 | BIT2));
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NbPciExpressDeviceInitialize
+//
+// Description: Init NB Pcie devices error register
+//
+// Input: IN UINT64 Address - PCIE devices Address
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NbPciExpressDeviceInitialize(
+ IN UINT64 Address
+)
+{
+ UINT8 Dev;
+ UINT8 Func;
+ UINT8 CurrentBus;
+ UINT16 Buffer16;
+ UINT64 DevAddress;
+ UINT8 PciFun = (Address >> 12) & 0x07;
+ UINT8 CapPtr;
+ UINT8 Buffer8;
+
+ CapPtr = NbFindCapPtr(Address, 0x10);
+ Buffer8 = READ_MEM8(Address + CapPtr + 0x08);
+ Buffer8 &= 0xF0;
+ Buffer8 |= (BIT03 | BIT02 | BIT01 | BIT00);
+
+ WRITE_MEM8_S3( gBootScript, \
+ Address + CapPtr + 0x08, \
+ Buffer8 );
+
+ CurrentBus = READ_MEM8((UINT32)Address + PCIBR_REG_SBUSN);
+
+ for (Dev = 0; Dev < 32; Dev++)
+ {
+ for (Func = 0; Func < 8; Func++)
+ {
+ DevAddress = (UINT64)NB_PCIE_CFG_ADDRESS(CurrentBus, Dev, Func, 0);
+
+ if (READ_MEM16(DevAddress) == 0xFFFF)
+ continue;
+
+ NbEnablePciDevErr(DevAddress);
+
+ Buffer16 = READ_MEM16((UINT32)NB_PCIE_CFG_ADDRESS(CurrentBus, Dev, 0, 0) + PCI_SCC);
+ if (Buffer16 == 0x0604)
+ {
+ DevAddress = (UINT64)NB_PCIE_CFG_ADDRESS(CurrentBus, Dev, 0, 0);
+ NbPciExpressDeviceInitialize(DevAddress);
+ }
+ }
+ }
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbInitAfterDeviceInstall
+//
+// Description: This callback function is called when a PCI I/O Protocol is
+// installed.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbInitAfterDeviceInstall (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN BufferSize = 20 * sizeof(EFI_HANDLE);
+ UINTN PciSeg;
+ UINTN PciBus;
+ UINTN PciDev;
+ UINTN PciFun;
+ UINT8 PciSeg8;
+ UINT8 PciBus8;
+ UINT8 PciDev8;
+ UINT8 PciFun8;
+ static UINT8 BrBus = 0;
+ UINT16 CapPtr16 = 0;
+ PCI_DEV_INFO *PciDevInfo = NULL;
+
+ Status = pBS->LocateHandle( ByRegisterNotify, NULL, gNBInitNotifyReg, \
+ &BufferSize, &Handle );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ // Locate PciIo protocol installed on Handle
+
+ Status = pBS->HandleProtocol( Handle, &gEfiPciIoProtocolGuid, &PciIo );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ // Get PCI Device Bus/Device/Function Numbers
+ Status = PciIo->GetLocation(PciIo, &PciSeg, &PciBus, &PciDev, &PciFun);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ PciSeg8 = (UINT8)PciSeg;
+ PciBus8 = (UINT8)PciBus;
+ PciDev8 = (UINT8)PciDev;
+ PciFun8 = (UINT8)PciFun;
+
+ if (NB_PCI_CFG_ADDRESS(PciBus, PciDev, PciFun, 0) == NB_PCIEBRN_BUS_DEV_FUN)
+ {
+
+ }
+
+ if (NB_PCI_CFG_ADDRESS(PciBus, PciDev, PciFun, 0) == NB_IGD_BUS_DEV_FUN) {
+
+ }
+
+ if ((BrBus != 0) && (PciBus == BrBus)) {
+
+ }
+
+ if (((UINT8)PciBus == PCIEBRN_BUS) && \
+ ((UINT8)PciDev == PCIEBRN_DEV) && \
+ (((UINT8)PciFun >= PCIEBRN_FUN) || ((UINT8)PciFun <= PCIEBRN_FUN2))) {
+
+ }
+
+ pBS->CloseEvent(Event);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: RegisterDisplayDIMMPopulationErrMsg
+//
+// Description: Notification function on SimpleIn protocol Installation
+//
+// Input: SystemTable - Pointer to the System Table
+//
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EFIAPI
+RegisterDisplayDIMMPopulationErrMsg (
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InstallNbMemoryInfo
+//
+// Description: This function collects all memory information and creates a
+// structure use for other DXE drivers.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallNbMemoryInfo (
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle=NULL;
+ EFI_GUID MemInfoHobGuid = EFI_MEMORY_RESTORE_DATA_GUID;
+ HOB_SAVE_MEMORY_DATA *MemInfoHob;
+ UINT8 node;
+ UINT8 Ch;
+ UINT8 Dimm;
+ UINT8 Slot0;
+ UINT8 Slot1;
+ UINT8 Slot2;
+ UINT8 Slot3;
+ VOID *FirstHob;
+ BOOLEAN MemoryTimingValuesInitialized;
+
+ //
+ // Get the HOB list and install MemInfo protocol
+ //
+ FirstHob = GetEfiConfigurationTable(SystemTable,&gHobListGuid);
+ if (!FirstHob)return EFI_INVALID_PARAMETER;
+
+ MemInfoHob = (HOB_SAVE_MEMORY_DATA *) FirstHob;
+
+ while (!EFI_ERROR (Status = FindNextHobByType (EFI_HOB_TYPE_GUID_EXTENSION, &MemInfoHob))) {
+ if (guidcmp (&MemInfoHob->EfiHobGuidType.Name, &MemInfoHobGuid) == 0) {
+ break;
+ }
+ }
+
+ MemoryTimingValuesInitialized = FALSE;
+
+ if (Status == EFI_SUCCESS) {
+ gMemInfoHobProtocol.MemInfoData.memSize = (UINT16)MemInfoHob->MrcData.SysOut.Outputs.MemoryMapData.TotalPhysicalMemorySize;
+ gMemInfoHobProtocol.MemInfoData.ddrFreq = (UINT16)MemInfoHob->MrcData.SysOut.Outputs.Frequency;
+ gMemInfoHobProtocol.MemInfoData.VddVoltage[0] = (UINT16)MemInfoHob->MrcData.SysOut.Outputs.VddVoltage[0];
+
+ gMemInfoHobProtocol.MemInfoData.EccSupport = MemInfoHob->MrcData.SysOut.Outputs.EccSupport;
+ gMemInfoHobProtocol.MemInfoData.RefClk = MemInfoHob->MrcData.SysOut.Outputs.RefClk;
+ gMemInfoHobProtocol.MemInfoData.Ratio = MemInfoHob->MrcData.SysOut.Outputs.Ratio;
+ NBPlatformData.DDR3Type = MemInfoHob->MrcData.SysOut.Outputs.DdrType;
+ gBClkFrequency = MemInfoHob->MrcData.SysIn.Inputs.BClkFrequency;
+ MemoryProfile = gMemInfoHobProtocol.MemInfoData.Profile = MemInfoHob->MrcData.SysIn.Inputs.MemoryProfile;
+
+ //
+ // Getting the tRAS
+ // See MRC_TimingConfiguration.c for tRAS algorithm
+ //
+ for (node = 0; node < NODE_NUM; node++) {
+ for (Ch = 0; Ch < CH_NUM; Ch++) {
+ for (Dimm = 0; Dimm < DIMM_NUM; Dimm++) {
+ gMemInfoHobProtocol.MemInfoData.dimmSize[(node << 2) + (Ch << 1) + Dimm] = (UINT16) MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Dimm[Dimm].DimmCapacity;
+ TRACE (
+ (TRACE_ALWAYS,
+ "Node %d Ch %d Dimm %d Size: %d\n",
+ node,
+ Ch,
+ Dimm,
+ gMemInfoHobProtocol.MemInfoData.dimmSize[(node << 2) + (Ch << 1) + Dimm])
+ );
+ gMemInfoHobProtocol.MemInfoData.DimmExist[(node << 2) + (Ch << 1) + Dimm] = (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Dimm[Dimm].Status == DIMM_PRESENT) ? TRUE : FALSE;
+ gMemInfoHobProtocol.MemInfoData.RankInDimm[(node << 2) + (Ch << 1) + Dimm] = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Dimm[Dimm].RankInDIMM;
+ gMemInfoHobProtocol.MemInfoData.DimmsSpdData[(node << 2) + (Ch << 1) + Dimm] = NULL;
+
+ //
+ // Updating tCL, tRCD and tRP to MemInfoHobProtocol from MemInfoHob
+ //
+ if (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Dimm[Dimm].Status == DIMM_PRESENT) {
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tCL = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tCL;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tCWL = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tCWL;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tFAW = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tFAW;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRAS = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRAS;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRC = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRC;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRCD = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRCD;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tREFI = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tREFI;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRFC = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRFC;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRP = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRP;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRRD = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRRD;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRTP = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRTP;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tWR = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tWR;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tWTR = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tWTR;
+ gMemInfoHobProtocol.MemInfoData.Timing[0].tRPab = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing[MemoryProfile].tRPab;
+
+ NBMrcTimingData = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing;
+
+ NBPlatformData.XmpProfile1 = (NBMrcTimingData[2].tCK != 0) ? TRUE : FALSE;
+ NBPlatformData.XmpProfile2 = (NBMrcTimingData[3].tCK != 0) ? TRUE : FALSE;
+
+ //
+ // mrc input spd send to smbios memory spd data.
+ //
+ if(gNbSetupData->IsRunMemoryDown)
+ gMemInfoHobProtocol.MemInfoData.DimmsSpdData[(node << 2) + (Ch << 1) + Dimm] = (UINT8*)&MemInfoHob->MrcData.SysIn.Inputs.Controller[0].Channel[Ch].Dimm[Dimm].Spd;
+
+// gMemInfoHobProtocol.MemInfoData.NMode = MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[Ch].Timing.NMode;
+ //
+ // Since we have only one setup varaiable to keep track of each memory timing, We inititialize the Memory Info HOB with the first occurence of data
+ //
+ MemoryTimingValuesInitialized = TRUE;
+ }
+ }
+ }
+ }
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 0
+#if defined APAC_NB_SETUP_SUPPORT || defined NB_SETUP_SUPPORT
+#if APAC_NB_SETUP_SUPPORT == 1 || NB_SETUP_SUPPORT == 1
+{
+ SETUP_DATA *SetupData = NULL;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ UINTN VarSize = 0;
+ WDT_PROTOCOL *WdtProtocol = NULL;
+ EFI_GUID WdtProtocolGuid = WDT_PROTOCOL_GUID;
+ UINT32 Attributes; // [ EIP167027 ]
+
+
+ if (MemoryTimingValuesInitialized) {
+ //Status = GetEfiVariable(L"Setup", &SetupGuid, NULL, &VarSize, &SetupData); // [ EIP167027 ]
+ Status = GetEfiVariable(L"Setup", &SetupGuid, &Attributes, &VarSize, &SetupData);
+ if (!EFI_ERROR(Status)) {
+ //
+
+ Status = pBS->LocateProtocol(&WdtProtocolGuid, NULL, &WdtProtocol);
+ if (!EFI_ERROR(Status)) {
+ if (WdtProtocol->CheckStatus() == V_PCH_OC_WDT_CTL_STATUS_FAILURE)
+ SetupData->SpdProfileSelected = 0; // Auto
+ }
+
+ SetupData->tCL = NBMrcTimingData[MemoryProfile].tCL;
+ SetupData->tCWL = NBMrcTimingData[MemoryProfile].tCWL;
+ SetupData->tFAW = NBMrcTimingData[MemoryProfile].tFAW;
+ SetupData->tRAS = NBMrcTimingData[MemoryProfile].tRAS;
+ SetupData->tRC = NBMrcTimingData[MemoryProfile].tRC;
+ SetupData->tRCD = NBMrcTimingData[MemoryProfile].tRCD;
+ SetupData->tREFI = NBMrcTimingData[MemoryProfile].tREFI;
+ SetupData->tRFC = NBMrcTimingData[MemoryProfile].tRFC;
+ SetupData->tRP = NBMrcTimingData[MemoryProfile].tRP;
+ SetupData->tRRD = NBMrcTimingData[MemoryProfile].tRRD;
+ SetupData->tRTP = NBMrcTimingData[MemoryProfile].tRTP;
+ SetupData->tWR = NBMrcTimingData[MemoryProfile].tWR;
+ SetupData->tWTR = NBMrcTimingData[MemoryProfile].tWTR;
+ SetupData->tRPab = NBMrcTimingData[MemoryProfile].tRPab;
+
+ SetupData->OcDdrFreqLimit = gMemInfoHobProtocol.MemInfoData.ddrFreq;
+
+ //Status = pRS->SetVariable ( // [ EIP167027 ]
+ // L"Setup",
+ // &SetupGuid,
+ // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ // sizeof(SETUP_DATA),
+ // SetupData);
+ Status = pRS->SetVariable (
+ L"Setup",
+ &SetupGuid,
+ Attributes,
+ sizeof(SETUP_DATA),
+ SetupData);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+}
+#endif
+#endif
+#endif
+
+ // Mobile - 0; Desktop - 2; UpServer - 3; FlavorWorkStation - 4;
+ if (NBPlatformData.UserBoard != FlavorMobile) {
+
+ Slot0 = (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[0].Dimm[0].Status == DIMM_PRESENT) ? TRUE : FALSE;
+ Slot1 = (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[0].Dimm[1].Status == DIMM_PRESENT) ? TRUE : FALSE;
+ Slot2 = (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[1].Dimm[0].Status == DIMM_PRESENT) ? TRUE : FALSE;
+ Slot3 = (MemInfoHob->MrcData.SysOut.Outputs.Controller[0].Channel[1].Dimm[1].Status == DIMM_PRESENT) ? TRUE : FALSE;
+
+ //
+ // Channel 0 Channel 1
+ // Slot0 Slot1 Slot0 Slot1 - Population AIO board
+ // 0 0 0 0 - Invalid - Invalid
+ // 0 0 0 1 - Valid - Invalid
+ // 0 0 1 0 - Invalid - Valid
+ // 0 0 1 1 - Valid - Valid
+ // 0 1 0 0 - Valid - Invalid
+ // 0 1 0 1 - Valid - Invalid
+ // 0 1 1 0 - Invalid - Invalid
+ // 0 1 1 1 - Valid - Invalid
+ // 1 0 0 0 - Invalid - Valid
+ // 1 0 0 1 - Invalid - Invalid
+ // 1 0 1 0 - Invalid - Valid
+ // 1 0 1 1 - Invalid - Valid
+ // 1 1 0 0 - Valid - Valid
+ // 1 1 0 1 - Valid - Invalid
+ // 1 1 1 0 - Invalid - Valid
+ // 1 1 1 1 - Valid - Valid
+ //
+ if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
+ RegisterDisplayDIMMPopulationErrMsg (SystemTable);
+ }
+ }
+
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gMemInfoProtocolGuid,
+ &gMemInfoHobProtocol,
+ NULL
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+#ifdef CSM_OPRROM_POLICY_GUID
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbCheckOprom
+//
+// Description: This callback function is called before/after processing all
+// PCI optonal ROM.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbCheckOprom (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ CSM_PLATFORM_POLICY_DATA *Data;
+ UINTN Seg;
+ UINTN Bus;
+ UINTN Dev;
+ UINTN Fun;
+
+ Status = pBS->LocateHandle( ByRegisterNotify, \
+ NULL, \
+ gCsmOpromReg, \
+ &BufferSize, \
+ &Handle );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ // Locate CSM Platform Policy data
+ Status = pBS->HandleProtocol( Handle, &gCsmOpromPolicyGuid, &Data );
+
+ if ( EFI_ERROR(Status) ) return;
+ if (Data == NULL) return;
+ if (Data->ExecuteThisRom == FALSE) return;
+ if(Data->PciIo == NULL) return;
+
+ Status = Data->PciIo->GetLocation( Data->PciIo, &Seg, &Bus, &Dev, &Fun );
+
+ // Close the event if needed.
+ // pBS->CloseEvent(Event);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbSetupNvramUpdatedCallback
+//
+// Description: This callback function is called after Setup NVRAM variable
+// being updated.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbSetupNvramUpdatedCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ NB_SETUP_DATA *NBSetupData = NULL;
+ UINTN VariableSize = sizeof(NB_SETUP_DATA);
+
+ Status = pBS->AllocatePool( EfiBootServicesData, \
+ VariableSize, \
+ &NBSetupData );
+ ASSERT_EFI_ERROR(Status);
+
+ GetNbSetupData( pRS, NBSetupData, FALSE );
+
+ // Free memory used for setup data
+ pBS->FreePool( NBSetupData );
+
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbPciEnumerationCompleteProtocolCallback
+//
+// Description: Install gEfiPciEnumerationCompleteProtocolGuid Protocol.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbPciEnumerationCompleteProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiPciEnumerationCompleteProtocolGuid = EFI_PCI_ENUMERATION_COMPLETE_GUID;
+ EFI_HANDLE Handle = NULL;
+
+ Status = pBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->CloseEvent(Event);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NbExitPmAuthProtocolCallback
+//
+// Description: This callback function is called after ExitPmAuthProtocol
+// being installed.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbExitPmAuthProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+ VOID *ProtocolPointer;
+ UINTN PegAddress;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT8 PegBus;
+ UINT8 PegDev;
+ UINT8 PegFun;
+ UINTN i;
+#if NB_PCIE_ERROR_LOG_SUPPORT
+ UINT8 CapPtr = 0;
+ EFI_SM_ELOG_PROTOCOL *GenericElogProtocol = NULL;
+#endif
+ //
+ // Check whether this is real ExitPmAuth notification, or just a SignalEvent
+ //
+ Status = pBS->LocateProtocol (&gExitPmAuthProtocolGuid, NULL, &ProtocolPointer);
+ if (EFI_ERROR (Status)) return;
+
+
+ for ( i = 0; gDevicesTable[i].Bus != 0xff; i++)
+ {
+
+ PegBus = gDevicesTable[i].Bus;
+ PegDev = gDevicesTable[i].Dev;
+ PegFun = gDevicesTable[i].Fun;
+
+ Data32 = READ_PCI32 (PegBus, PegDev, PegFun, PCI_VID);
+
+ if (Data32 == 0xFFFFFFFF) continue;
+
+ //
+ // 6.3.7 Virtual Channel Configuration of PCI Express Port
+ // Set the VC0RCTL register D1:F0 Offset 114h [7:1] = 7Fh
+ //
+ PegAddress = NB_PCIE_CFG_ADDRESS(PegBus, PegDev, PegFun, 0);
+ Data32And = 0xFFFFFF00 + BIT0;
+ Data32Or = BIT1 + BIT2 + BIT3 + BIT4 + BIT5 +BIT6 + BIT7;
+ RW_MEM32_S3(gBootScript, (PegAddress + R_SA_PEG_VC0RCTL0_OFFSET), Data32Or, ~Data32And);
+
+ //
+ // Store the Root port Bus assignemnt for S3 resume path
+ //
+ PegAddress = NB_PCIE_CFG_ADDRESS(PegBus, PegDev, PegFun, PCI_PBUS);
+ Data32 = READ_MEM32 (PegAddress);
+
+ BOOT_SCRIPT_S3_MEM_WRITE_MACRO( \
+ gBootScript, \
+ EfiBootScriptWidthUint32, \
+ PegAddress, \
+ 1, \
+ &Data32 );
+
+ PegAddress = NB_PCIE_CFG_ADDRESS(PegBus, PegDev, PegFun, PCI_BAR3);
+ Data16 = READ_MEM16 (PegAddress);
+
+ BOOT_SCRIPT_S3_MEM_WRITE_MACRO( \
+ gBootScript, \
+ EfiBootScriptWidthUint16, \
+ PegAddress, \
+ 1, \
+ &Data16 );
+
+#if NB_PCIE_ERROR_LOG_SUPPORT
+ Status = pBS->LocateProtocol( &gElogProtocolGuid,
+ NULL,
+ &GenericElogProtocol );
+ if (!EFI_ERROR (Status)) {
+ PegAddress = NB_PCIE_CFG_ADDRESS(PegBus, PegDev, PegFun, 0);
+ // if enable PCI SERR and PERR
+ if((READ_MEM16(PegAddress + PCI_CMD) & (BIT6 | BIT8)) == (BIT6 | BIT8))
+ {
+ NbPciExpressDeviceInitialize(PegAddress);
+
+ // Clear Error status
+ WRITE_MEM8_S3(gBootScript, PegAddress + 0x07, 0xff);
+ WRITE_MEM8_S3(gBootScript, PegAddress + 0x1F, 0xff);
+
+ CapPtr = NbFindCapPtr(PegAddress, 0x10);
+
+ if (CapPtr != 0)
+ {
+ // Clear Device Error status
+ SET_MEM8_S3(gBootScript, PegAddress + CapPtr + 0x0A, (BIT0 | BIT1 | BIT2));
+ // Enable the error bits of Device Control
+ SET_MEM8_S3(gBootScript, PegAddress + CapPtr + 0x08, (BIT0 | BIT1 | BIT2));
+ // Enable the error bits of Root Control
+ SET_MEM8_S3(gBootScript, PegAddress + CapPtr + 0x1C, (BIT2));
+ }
+ }
+ }
+#endif
+
+ }
+
+ pBS->CloseEvent(Event);
+
+}
+
+//----------------------------------------------------------------------------
+#if (ACPI_SUPPORT)
+
+UINT8 ACPI_OEM_ID[6] = CONVERT_TO_STRING(T_ACPI_OEM_ID);
+UINT8 ACPI_OEM_TBL_ID[8] = CONVERT_TO_STRING(T_ACPI_OEM_TBL_ID);
+
+UINTN mMcfgTblHandle=0;
+EFI_EVENT mAcpiEvent;
+VOID *mAcpiReg;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CreateNbAcpiCallback
+//
+// Description: This function will create all ACPI components for NB when
+// ACPI support protocol is available.
+//
+// Input: Event - Event of callback
+// Context - Context of callback.
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateNbAcpiCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ MCFG_20 *mcfg;
+ EFI_ACPI_TABLE_PROTOCOL *At;
+ UINT8 i;
+ UINTN TableKey;
+
+ // It must be only one instance of such protocol
+ Status = pBS->LocateProtocol( &gEfiAcpiTableProtocolGuid, NULL, &At );
+ TRACE((-1,"PciHostCSHooks: LocateProtocol(ACPITableProtocol) = %r\n", Status));
+ if(EFI_ERROR(Status)) return;
+
+//--------------------------------
+ //it must be only one instance of such protocol
+ mcfg=MallocZ(sizeof(MCFG_20));
+ ASSERT(mcfg);
+ if(!mcfg) return;
+
+ //Fill Table header;
+ mcfg->Header.Signature=MCFG_SIG;
+ mcfg->Header.Length=sizeof(MCFG_20);
+ mcfg->Header.Revision=1;
+ mcfg->Header.Checksum=0;
+ for (i=0;i<6;i++) {
+ mcfg->Header.OemId[i]=ACPI_OEM_ID[i];
+ }
+
+ for (i=0;i<8;i++) {
+ mcfg->Header.OemTblId[i]=ACPI_OEM_TBL_ID[i];
+ }
+ mcfg->Header.OemRev=ACPI_OEM_REV;
+ mcfg->Header.CreatorId=0x5446534d; // "MSFT" 4D 53 46 54
+ mcfg->Header.CreatorRev=0x97;
+
+ //fill MCFG Fields
+ mcfg->BaseAddr=PCIEX_BASE_ADDRESS; // Base address of 256MB extended config space
+ mcfg->PciSeg=0; // Segment # of PCI Bus
+ mcfg->StartBus=0; // Start bus number of PCI segment
+ mcfg->EndBus=(UINT8)((PCIEX_LENGTH >> 20) - 1);// End bus number of PCI segment
+
+ // Add table
+ Status = At->InstallAcpiTable( At, mcfg, sizeof(MCFG_20), &TableKey );
+ TRACE((-1,"PciHostCSHooks: ACPITable->InstallAcpiTable(MCFG)=%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+
+ //free memory used for table image
+ pBS->FreePool(mcfg);
+
+ //Kill the Event
+ pBS->CloseEvent(Event);
+
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CreateNbAcpiComponent
+//
+// Description: This function creates all ACPI components supported by NB.
+//
+// Input: None
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateNbAcpiComponent (VOID)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if (ACPI_SUPPORT)
+ Status = RegisterProtocolCallback( &gEfiAcpiTableProtocolGuid, \
+ CreateNbAcpiCallback, \
+ NULL, \
+ &mAcpiEvent, \
+ &mAcpiReg );
+ // If System Description Table Protocol has been installed we can use
+ // it rigth on the way
+ pBS->SignalEvent( mAcpiEvent );
+#endif
+
+}
+
+// Protocols that are installed
+DXE_PLATFORM_SA_POLICY_PROTOCOL mDxePlatformSaPolicy = { 0 };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InstallDxePlatformSaPolicy
+//
+// Description: This Function installs the SNB SA POLICY PROTOCOL
+//
+// Input: None
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InstallDxePlatformSaPolicy (VOID)
+{
+ VOID *Registration;
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ EFI_STATUS FindNbPegHobStatus = EFI_NOT_FOUND;
+ EFI_HANDLE Handle;
+ VOID *HobData;
+ SB_SETUP_DATA *SBSetupData = NULL;
+ UINTN VariableSize = sizeof(SB_SETUP_DATA);
+ UINT8 Index;
+ UINT16 McDeviceId;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx, CpuSteppingId, CpuFamilyId;
+
+ Status = pBS->AllocatePool( EfiBootServicesData, \
+ VariableSize, \
+ &SBSetupData );
+ ASSERT_EFI_ERROR(Status);
+
+ // Read the Setup Data
+ GetSbSetupData( pRS, SBSetupData, FALSE );
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SA_VTD_CONFIGURATION),
+ &(mDxePlatformSaPolicy.Vtd)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SA_MEMORY_CONFIGURATION),
+ &(mDxePlatformSaPolicy.MemoryConfig)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ (sizeof (UINT8) * DIMM_SLOT_NUM),
+ (VOID **) &mDxePlatformSaPolicy.MemoryConfig->SpdAddressTable
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (SA_PCIE_CONFIGURATION),
+ &(mDxePlatformSaPolicy.PcieConfig)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (SA_IGD_CONFIGURATION),
+ &(mDxePlatformSaPolicy.IgdConfig)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (SA_MISC_CONFIGURATION),
+ &(mDxePlatformSaPolicy.MiscConfig)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SA_DEFAULT_SVID_SID),
+ (VOID **) &mDxePlatformSaPolicy.MiscConfig->DefaultSvidSid
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SA_HDA_VERB_TABLE),
+ (VOID **) &mDxePlatformSaPolicy.MiscConfig->SaHdaVerbTable
+ );
+ ASSERT_EFI_ERROR (Status);
+#if ( defined(SwitchableGraphics_SUPPORT) && (SwitchableGraphics_SUPPORT == 1) )
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SA_DEFAULT_SVID_SID),
+ (VOID **) &mDxePlatformSaPolicy.VbiosConfig
+ );
+ ASSERT_EFI_ERROR (Status);
+#endif
+
+ // RMRR Base and Limit Address for USB
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ (sizeof (EFI_PHYSICAL_ADDRESS) * 2),
+ (VOID **) &mDxePlatformSaPolicy.Vtd->RmrrUsbBaseAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Read MC device ID
+ McDeviceId = READ_PCI16_NB(R_SA_MC_DEVICE_ID);
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ CpuSteppingId = RegEax & 0x0000000F;
+ CpuFamilyId = RegEax & 0x0FFF0FF0;
+
+ NBPlatformData.VTdAvailable = (READ_PCI32_NB(0xe4) & BIT23) ? 0 : 1;
+
+
+ mDxePlatformSaPolicy.MemoryConfig->SpdAddressTable[0] = DIMM1_SMBUS_ADDRESS;
+ mDxePlatformSaPolicy.MemoryConfig->SpdAddressTable[1] = DIMM2_SMBUS_ADDRESS;
+ mDxePlatformSaPolicy.MemoryConfig->SpdAddressTable[2] = DIMM3_SMBUS_ADDRESS;
+ mDxePlatformSaPolicy.MemoryConfig->SpdAddressTable[3] = DIMM4_SMBUS_ADDRESS;
+
+ mDxePlatformSaPolicy.MemoryConfig->ChannelASlotMap = 0x03;
+ mDxePlatformSaPolicy.MemoryConfig->ChannelBSlotMap = 0x03;
+
+#if A1_MEMORY_SOCKETS == 2
+ mDxePlatformSaPolicy.MemoryConfig->ChannelASlotMap = 0x01;
+ mDxePlatformSaPolicy.MemoryConfig->ChannelBSlotMap = 0x01;
+#endif
+
+#if A1_MEMORY_SOCKETS == 6
+ mDxePlatformSaPolicy.MemoryConfig->ChannelASlotMap = 0x07;
+ mDxePlatformSaPolicy.MemoryConfig->ChannelBSlotMap = 0x07;
+#endif
+
+
+ mDxePlatformSaPolicy.Vtd->BaseAddress[0] = NB_VTD_BASE_ADDRESS;
+ mDxePlatformSaPolicy.Vtd->BaseAddress[1] = NB_VTD_BASE_ADDRESS + 0x1000;
+
+ // System Agent Configuration Misc
+
+ mDxePlatformSaPolicy.MiscConfig->ChapDeviceEnable = gNbSetupData->SaDevice7;;
+ mDxePlatformSaPolicy.MiscConfig->Device4Enable = (gNbSetupData->SaDevice4);
+ mDxePlatformSaPolicy.MiscConfig->CridEnable = gNbSetupData->EnableNbCrid;
+ mDxePlatformSaPolicy.MiscConfig->DefaultSvidSid->SubSystemVendorId = gNbSetupData->NBDxeSubSystemVendorId;
+ mDxePlatformSaPolicy.MiscConfig->DefaultSvidSid->SubSystemId = gNbSetupData->NBDxeSubSystemId;
+
+ mDxePlatformSaPolicy.MiscConfig->AudioEnable = gNbSetupData->SaAudioEnable;
+ mDxePlatformSaPolicy.MiscConfig->FviReport = 1; // Default Enable FVI SMBIOS Report
+ mDxePlatformSaPolicy.MiscConfig->FviSmbiosType = 0xDD; // Default SMBIOS Type 221
+
+ // Port B
+// gNbSaHdaVerbTableData[4] &= 0xFFFFFF00;
+// if (gNbSetupData->SaHdmiCodecPortB == 0)
+// gNbSaHdaVerbTableData[4] |= 0x58;
+// else
+// gNbSaHdaVerbTableData[4] |= 0x18;
+
+ // Port C
+// gNbSaHdaVerbTableData[8] &= 0xFFFFFF00;
+// if (gNbSetupData->SaHdmiCodecPortC == 0)
+// gNbSaHdaVerbTableData[8] |= 0x58;
+// else
+// gNbSaHdaVerbTableData[8] |= 0x18;
+
+ // Port D
+// gNbSaHdaVerbTableData[12] &= 0xFFFFFF00;
+// if (gNbSetupData->SaHdmiCodecPortD == 0)
+// gNbSaHdaVerbTableData[12] |= 0x58;
+// else
+// gNbSaHdaVerbTableData[12] |= 0x18;
+
+// if ((CpuFamilyId == 0x000306C0) && (CpuSteppingId < 2)) { // B0
+
+ if (gNbSetupData->NbSaHdaVerbTable != NULL) {
+ mDxePlatformSaPolicy.MiscConfig->SaHdaVerbTableNum = gNbSetupData->NbSaHdaVerbTableNum;
+ (pBS->CopyMem) (&mDxePlatformSaPolicy.MiscConfig->SaHdaVerbTable[0], &gNbSetupData->NbSaHdaVerbTable[0], sizeof (SA_HDA_VERB_TABLE_HEADER));
+ mDxePlatformSaPolicy.MiscConfig->SaHdaVerbTable[0].VerbTableData = gNbSetupData->NbSaHdaVerbTable[0].VerbTableData;
+ }
+
+// } else {
+// mDxePlatformSaPolicy.MiscConfig->SaHdaVerbTable[0].VerbTableData = &(gNbSaHdaVerbTableData[1]);
+// }
+
+ //
+ // BIOS must update USB RMRR base address
+ //
+ mDxePlatformSaPolicy.Vtd->RmrrUsbBaseAddress[0] = 0x3E2E0000;
+ mDxePlatformSaPolicy.Vtd->RmrrUsbBaseAddress[1] = 0x3E2FFFFF;
+
+ // Protocol revision number
+ mDxePlatformSaPolicy.Revision = DXE_SA_PLATFORM_POLICY_PROTOCOL_REVISION_8;
+
+ // Init DxePlaformSaPolicy if Setup Variable is exist
+ mDxePlatformSaPolicy.Vtd->VtdEnable = gNbSetupData->EnableVtd;
+
+ // PCIE related Setup data
+ mDxePlatformSaPolicy.PcieConfig->DmiAspm = gNbSetupData->NBDmiAspm;
+ mDxePlatformSaPolicy.PcieConfig->DmiExtSync = gNbSetupData->NBDmiExtSync;
+ mDxePlatformSaPolicy.PcieConfig->DmiDeEmphasis = gNbSetupData->DmiDeEmphasis;
+ mDxePlatformSaPolicy.PcieConfig->DmiIot = gNbSetupData->DmiIot;
+ mDxePlatformSaPolicy.PcieConfig->C7Allowed = gNbSetupData->C7Allowed;
+ for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+ mDxePlatformSaPolicy.PcieConfig->PegPwrOpt[Index].LtrEnable = gNbSetupData->LtrEnable[Index];
+ mDxePlatformSaPolicy.PcieConfig->PegPwrOpt[Index].LtrMaxSnoopLatency = gNbSetupData->LtrMaxSnoopLatency[Index];//V_SA_LTR_MAX_SNOOP_LATENCY_VALUE;
+ mDxePlatformSaPolicy.PcieConfig->PegPwrOpt[Index].LtrMaxNoSnoopLatency = gNbSetupData->LtrMaxNoSnoopLatency[Index];//V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+ mDxePlatformSaPolicy.PcieConfig->PegPwrOpt[Index].ObffEnable = gNbSetupData->ObffEnable[Index];
+ }
+
+
+
+ if (gNbSetupData->DetectNonComplaint == 1) {
+ HobData = (EFI_HOB_GENERIC_HEADER *) GetEfiConfigurationTable (pST, &gHobListGuid);
+ if (HobData) {
+ FindNbPegHobStatus = FindNextHobByGuid (&gAmiNbPegInfoGuid, &HobData);
+ }
+ }
+
+ for (Index = 0; Index < 3; Index++) {
+ mDxePlatformSaPolicy.PcieConfig->PegAspm[Index] = gNbSetupData->PegAspm[Index];
+ mDxePlatformSaPolicy.PcieConfig->PegAspmL0s[Index] = gNbSetupData->PegAspmL0s[Index];
+ if (EFI_ERROR (FindNbPegHobStatus)) {
+ mDxePlatformSaPolicy.PcieConfig->PegDeEmphasis[Index] = gNbSetupData->PegDeEmphasis[Index];
+ } else {
+ mDxePlatformSaPolicy.PcieConfig->PegDeEmphasis[Index] = ((NB_PEG_INFO_HOB *)HobData)->PegDeOverride[Index];
+ }
+ }
+
+ mDxePlatformSaPolicy.PcieConfig->PcieAspmDevsOverride = mPcieAspmDevsOverride;
+ mDxePlatformSaPolicy.PcieConfig->PcieLtrDevsOverride = mPcieLtrDevsOverride;
+
+ // IGD related Setup data
+ mDxePlatformSaPolicy.IgdConfig->RenderStandby = gNbSetupData->RenderStandby;
+
+ mDxePlatformSaPolicy.IgdConfig->DeepRenderStandby = gNbSetupData->DeepRenderStandby;
+
+ if (GetPchSeries() == PchLp) {
+ mDxePlatformSaPolicy.IgdConfig->CdClk = 1;
+ } else {
+ mDxePlatformSaPolicy.IgdConfig->CdClk = 2; // (EIP106013)
+ }
+
+
+ mDxePlatformSaPolicy.IgdConfig->PlatformConfig = gNbSetupData->AcpiLowPowerS0Idle;
+
+
+#ifdef BDAT_SUPPORT
+ mDxePlatformSaPolicy.MemoryConfig->RmtBdatEnable = gNbSetupData->BdatAcpiTableSupport;
+#endif
+
+#if ( defined(SwitchableGraphics_SUPPORT) && (SwitchableGraphics_SUPPORT == 1) )
+ ///
+ /// Initialize the Switchable Graphics DXE Policies
+ ///
+
+ ///
+ /// 1 = Load secondary display device VBIOS
+ /// 0 = Do not load
+ ///
+ mDxePlatformSaPolicy.VbiosConfig->LoadVbios = 0; // Shark Bay SA Reference Code Production Version 1.9.0 [ EIP194524 ]
+ ///
+ /// 1 = Execute the secondary display device VBIOS (only if LoadVbios == 1)
+ /// 0 = Do no execute
+ ///
+ mDxePlatformSaPolicy.VbiosConfig->ExecuteVbios = 0;
+ ///
+ /// 1 = secondary display device VBIOS Source is PCI Card
+ /// 0 = secondary display device VBIOS Source is FW Volume
+ ///
+ mDxePlatformSaPolicy.VbiosConfig->VbiosSource = 1;
+#endif
+
+ Handle = NULL;
+ // Install protocol to to allow access to this Policy.
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gDxePlatformSaPolicyGuid,
+ &mDxePlatformSaPolicy,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ // Register Callback function for updating USB Rmrr address
+ Status = pBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ RmrrUpdateCallback,
+ NULL,
+ &Event
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiUsbProtocolGuid,
+ Event,
+ &Registration
+ );
+ }
+
+ // Free memory used for setup data
+ pBS->FreePool( SBSetupData );
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------
+//
+// Procedure: RmrrUpdateCallback
+//
+// Description: This Function is update IGD & USB Rmrr BaseAddress
+//
+// Input: Event A pointer to the Event that triggered the callback.
+// Context A pointer to private data registered with the callback function.
+//
+// Output: None
+//--------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RmrrUpdateCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *UsbProtocol;
+ DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy;
+ UINT16 IgdMode;
+ UINT16 GttMode;
+ UINT32 IgdMemSize;
+ UINT32 GttMemSize;
+ EFI_PHYSICAL_ADDRESS RmrrIGDBaseAddress;
+ EFI_PHYSICAL_ADDRESS RmrrIGDSize;
+ DXE_SERVICES *DxeSvcTbl = NULL;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor;
+ UINT64 Attributes;
+
+ pBS->CloseEvent(Event);
+ //
+ // Update USB Reserved Memory Base Address and Limit Address for VT-d.
+ //
+ Status = pBS->LocateProtocol (&gDxePlatformSaPolicyGuid, NULL, &DxePlatformSaPolicy);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiUsbProtocolGuid, NULL, &UsbProtocol);
+ if (!EFI_ERROR (Status))
+ {
+
+ Status = UsbProtocol->UsbGetRuntimeRegion (
+ &DxePlatformSaPolicy->Vtd->RmrrUsbBaseAddress[0],
+ &DxePlatformSaPolicy->Vtd->RmrrUsbBaseAddress[1]
+ );
+
+ TRACE ((TRACE_ALWAYS, "RmrrUsbBaseAddress = 0x%X\n", DxePlatformSaPolicy->Vtd->RmrrUsbBaseAddress[0]));
+ TRACE ((TRACE_ALWAYS, "RmrrUsbLimitAddress = 0x%X\n", DxePlatformSaPolicy->Vtd->RmrrUsbBaseAddress[1]));
+ }
+
+ if (READ_PCI32_IGD (R_SA_IGD_VID) == 0xFFFFFFFF) return Status;
+
+ Status = LibGetDxeSvcTbl(&DxeSvcTbl);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) return Status;
+
+ //
+ // Calculate IGD memsize
+ //
+ IgdMode = (READ_PCI16_NB (R_SA_GGC) & B_SA_GGC_GMS_MASK) >> 3;
+ if (IgdMode <= V_SA_GGC_GMS_512MB)
+ {
+ IgdMemSize = IgdMode * 32 * (1024) * (1024);
+ } else if (IgdMode >= 0x11) // V_SA_GGC_GMS_1024MB
+ {
+ IgdMemSize = 0x20 * 32 * (1024) * (1024);
+ } else {
+ IgdMemSize = 0;
+ }
+
+ //
+ // Calculate GTT mem size
+ //
+ GttMode = (READ_PCI16_NB (R_SA_GGC) & B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
+ if (GttMode <= V_SA_GGC_GGMS_2MB)
+ {
+ GttMemSize = GttMode * (1024) * (1024);
+ } else {
+ GttMemSize = 0;
+ }
+
+ if ((IgdMemSize + GttMemSize) == 0) return Status;
+
+ RmrrIGDBaseAddress = (EFI_PHYSICAL_ADDRESS)((READ_PCI32_NB (R_SA_TOLUD) & ~(0x01)) - IgdMemSize - GttMemSize);
+ RmrrIGDSize = (EFI_PHYSICAL_ADDRESS)(IgdMemSize + GttMemSize);
+
+ Status = DxeSvcTbl->GetMemorySpaceDescriptor (RmrrIGDBaseAddress, &GcdMemorySpaceDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes = GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
+
+ Status=DxeSvcTbl->SetMemorySpaceAttributes(RmrrIGDBaseAddress,RmrrIGDSize,Attributes);
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE ((TRACE_ALWAYS, "RmrrIGDBaseAddress = 0x%X\n", RmrrIGDBaseAddress));
+ TRACE ((TRACE_ALWAYS, "RmrrIGDSize = 0x%X\n", RmrrIGDSize));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------
+//
+// Procedure: NBDXE_ShadowRam
+//
+// Description: For setting PAM0\PAM5\PAM6 to "Disable", "Read Only", "Write Only", or "R/W Enable"
+// under not using legacy.
+//
+// Input: EFI_HANDLE
+// EFI_SYSTEM_TABL
+//
+// Output: None
+//--------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS NBDXE_ShadowRam (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Default_PAM0 = (UINT8)(NB_F0000_PAM0 << 4);
+ UINT8 Default_PAM5 = (UINT8)((NB_E0000_PAM5 << 4) | NB_E0000_PAM5);
+ UINT8 Default_PAM6 = (UINT8)((NB_E8000_PAM6 << 4) | NB_E8000_PAM6);
+
+ //
+ // Set "Disable", "Read Only", "Write Only", or "R/W Enable" as Token value into PAM0\PAM5\PAM6.
+ //
+ WRITE_PCI8_NB (0x80, Default_PAM0);
+ WRITE_PCI8_NB (0x85, Default_PAM5);
+ WRITE_PCI8_NB (0x86, Default_PAM6);
+
+ return Status;
+}
+
+
+#if defined (PERF_TUNE_SUPPORT) && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+#define OC_MAILBOX_MSR 0x00000150
+#define MAILBOX_WAIT_TIMEOUT 1000 ///< 1 millisecond
+#define OC_LIB_CMD_GET_OC_CAPABILITIES 0x01
+#define OC_LIB_CMD_GET_VOLTAGE_FREQUENCY 0x10
+#define OC_LIB_COMPLETION_CODE_SUCCESS 0x00
+#define BIT0_MASK 0x1
+#define MAX_RATIO_MASK 0x000000FF
+#define VOLTAGE_TARGET_MASK 0x000FFF00
+#define VOLTAGE_TARGET_OFFSET 8
+#define VOLTAGE_MODE_MASK 0x00100000
+#define VOLTAGE_MODE_OFFSET 20
+#define VOLTAGE_OFFSET_MASK 0xFFE00000
+#define VOLTAGE_OFFSET_OFFSET 21
+
+#define MILLIVOLTS_PER_VOLT 1000
+#define MAX_TARGET_MV 4095
+#define MAX_OFFSET_MV 500
+
+#define CONVERT_TO_FIXED_POINT_VOLTS 0
+#define CONVERT_TO_BINARY_MILLIVOLT 1
+
+#define OC_CAPS_MAX_RATIO_MASK 0x000000FF
+#define OC_CAPS_RATIO_SUPPORT_MASK 0x00000100
+#define OC_CAPS_RATIO_SUPPORT_OFFSET 8
+#define OC_CAPS_OVERRIDE_SUPPORT_MASK 0x00000200
+#define OC_CAPS_OVERRIDE_SUPPORT_OFFSET 9
+#define OC_CAPS_OFFSET_SUPPORT_MASK 0x00000400
+#define OC_CAPS_OFFSET_SUPPORT_OFFSET 10
+//
+// Bit 10 is the S11.0.10V sign bit
+//
+#define FIXED_POINT_SIGN_BIT_MASK 0x0400
+#define INT16_SIGN_BIT_MASK 0x8000
+
+//
+// tCL Macro definitions
+//
+#ifndef tCL_MINIMUM
+#define tCL_MINIMUM 4
+#endif
+#ifndef tCL_MAXIMUM
+#define tCL_MAXIMUM 18
+#endif
+#define tCL_NumOfValues tCL_MAXIMUM - tCL_MINIMUM + 1
+//
+// tRP Macro definitions
+//
+#ifndef tRP_MINIMUM
+#define tRP_MINIMUM 4
+#endif
+#ifndef tRP_MAXIMUM
+#define tRP_MAXIMUM 15
+#endif
+#define tRP_NumOfValues tRP_MAXIMUM - tRP_MINIMUM + 1
+//
+// tRCD Macro definitions
+//
+#ifndef tRCD_MINIMUM
+#define tRCD_MINIMUM 4
+#endif
+#ifndef tRCD_MAXIMUM
+#define tRCD_MAXIMUM 20
+#endif
+#define tRCD_NumOfValues tRCD_MAXIMUM - tRCD_MINIMUM + 1
+//
+// tRAS Macro definitions
+//
+#ifndef tRAS_MINIMUM
+#define tRAS_MINIMUM 10
+#endif
+#ifndef tRAS_MAXIMUM
+#define tRAS_MAXIMUM 40
+#endif
+#define tRAS_NumOfValues tRAS_MAXIMUM - tRAS_MINIMUM + 1
+//
+// tWR Macro definitions
+//
+#ifndef tWR_MINIMUM
+#define tWR_MINIMUM 5
+#endif
+#ifndef tWR_MAXIMUM
+#define tWR_MAXIMUM 30
+#endif
+#define tWR_NumOfValues tWR_MAXIMUM - tWR_MINIMUM + 1
+//
+// tRFC Macro definitions
+//
+#ifndef tRFC_MINIMUM
+#define tRFC_MINIMUM 1
+#endif
+#ifndef tRFC_MAXIMUM
+#define tRFC_MAXIMUM 511
+#endif
+#define tRFC_NumOfValues tRFC_MAXIMUM - tRFC_MINIMUM + 1
+//
+// tRRD Macro definitions
+//
+#ifndef tRRD_MINIMUM
+#define tRRD_MINIMUM 4
+#endif
+#ifndef tRRD_MAXIMUM
+#define tRRD_MAXIMUM 7
+#endif
+#define tRRD_NumOfValues tRRD_MAXIMUM - tRRD_MINIMUM + 1
+//
+// tWTR Macro definitions
+//
+#ifndef tWTR_MINIMUM
+#define tWTR_MINIMUM 4
+#endif
+#ifndef tWTR_MAXIMUM
+#define tWTR_MAXIMUM 10
+#endif
+#define tWTR_NumOfValues tWTR_MAXIMUM - tWTR_MINIMUM + 1
+//
+// tRTP Macro definitions
+//
+#ifndef tRTP_MINIMUM
+#define tRTP_MINIMUM 4
+#endif
+#ifndef tRTP_MAXIMUM
+#define tRTP_MAXIMUM 15
+#endif
+
+#define tRTP_NumOfValues tRTP_MAXIMUM - tRTP_MINIMUM + 1
+//
+// tFAW Macro definitions
+//
+#ifndef tFAW_MINIMUM
+#define tFAW_MINIMUM 10
+#endif
+#ifndef tFAW_MAXIMUM
+#define tFAW_MAXIMUM 54
+#endif
+#define tFAW_NumOfValues tFAW_MAXIMUM - tFAW_MINIMUM + 1
+//
+// tRC Macro definitions
+//
+#ifndef tRC_MINIMUM
+#define tRC_MINIMUM 1
+#endif
+#ifndef tRC_MAXIMUM
+#define tRC_MAXIMUM 4095
+#endif
+#define tRC_NumOfValues tRC_MAXIMUM - tRC_MINIMUM + 1
+//
+//
+// tCWL Macro definitions
+//
+#ifndef tCWL_MINIMUM
+#define tCWL_MINIMUM 5
+#endif
+#ifndef tCWL_MAXIMUM
+#define tCWL_MAXIMUM 12
+#endif
+#define tCWL_NumOfValues tCWL_MAXIMUM - tCWL_MINIMUM + 1
+//
+// tREFI Macro definitions
+//
+#ifndef tREFI_MINIMUM
+#define tREFI_MINIMUM 1
+#endif
+#ifndef tREFI_MAXIMUM
+#define tREFI_MAXIMUM 10000
+#endif
+#define tREFI_NumOfValues tREFI_MAXIMUM - tREFI_MINIMUM + 1
+//
+// tRPab Macro definitions
+//
+#ifndef tRPab_MINIMUM
+#define tRPab_MINIMUM 4
+#endif
+#ifndef tRPab_MAXIMUM
+#define tRPab_MAXIMUM 18
+#endif
+#define tRPab_NumOfValues tRPab_MAXIMUM - tRPab_MINIMUM + 1
+//
+//
+// iGfxRatio Macro definitions
+//
+#ifndef iGfxRatio_MINIMUM
+#define iGfxRatio_MINIMUM 17
+#endif
+#ifndef iGfxRatio_MAXIMUM
+#define iGfxRatio_MAXIMUM 60
+#endif
+#define iGfxRatio_NumOfValues iGfxRatio_MAXIMUM - iGfxRatio_MINIMUM + 1
+
+//
+// iGfxVolt Macro definitions
+//
+#ifndef iGfxVoltOverride_MINIMUM
+#define iGfxVoltOverride_MINIMUM 0
+#endif
+#ifndef iGfxVoltOverride_MAXIMUM
+#define iGfxVoltOverride_MAXIMUM 2000
+#endif
+#define iGfxVoltOverride_NumOfValues iGfxVoltOverride_MAXIMUM - iGfxVoltOverride_MINIMUM + 1
+
+#ifndef iGfxVoltOffset_MINIMUM
+#define iGfxVoltOffset_MINIMUM 0
+#endif
+#ifndef iGfxVoltOffset_MAXIMUM
+#define iGfxVoltOffset_MAXIMUM 1000
+#endif
+#define iGfxVoltOffset_NumOfValues iGfxVoltOffset_MAXIMUM - iGfxVoltOffset_MINIMUM + 1
+
+#ifndef SaVoltOffset_MINIMUM
+#define SaVoltOffset_MINIMUM 0
+#endif
+#ifndef SaVoltOffset_MAXIMUM
+#define SaVoltOffset_MAXIMUM 1000
+#endif
+#define SaVoltOffset_NumOfValues SaVoltOffset_MAXIMUM - SaVoltOffset_MINIMUM + 1
+
+#ifndef IoaVoltOffset_MINIMUM
+#define IoaVoltOffset_MINIMUM 0
+#endif
+#ifndef IoaVoltOffset_MAXIMUM
+#define IoaVoltOffset_MAXIMUM 1000
+#endif
+#define IoaVoltOffset_NumOfValues IoaVoltOffset_MAXIMUM - IoaVoltOffset_MINIMUM + 1
+
+#ifndef IodVoltOffset_MINIMUM
+#define IodVoltOffset_MINIMUM 0
+#endif
+#ifndef IodVoltOffset_MAXIMUM
+#define IodVoltOffset_MAXIMUM 1000
+#endif
+#define IodVoltOffset_NumOfValues IodVoltOffset_MAXIMUM - IodVoltOffset_MINIMUM + 1
+
+//========================================== GACI TABLE ======================================================
+
+// GACI_DATA DevNameGaciData {ControlID,NumberOfValues,\
+// Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+static GACI_DATA tCLGaciData = {BIOS_TCL_IMPLEMENTATION,\
+ tCL_NumOfValues, 0, 0, 0, tCL_MINIMUM, tCL_MAXIMUM, tCL_MINIMUM, tCL_MAXIMUM};
+
+static GACI_DATA tCWLGaciData = {BIOS_TCWL_IMPLEMENTATION,\
+ tCWL_NumOfValues, 0, 0, 0, tCWL_MINIMUM, tCWL_MAXIMUM, tCWL_MINIMUM, tCWL_MAXIMUM};
+
+static GACI_DATA tREFIGaciData = {BIOS_TREFI_IMPLEMENTATION,\
+ tREFI_NumOfValues, 0, 0, 0, tREFI_MINIMUM, tREFI_MAXIMUM, tREFI_MINIMUM, tREFI_MAXIMUM};
+
+static GACI_DATA tRASGaciData = {BIOS_TRAS_IMPLEMENTATION,\
+ tRAS_NumOfValues, 0, 0, 0, tRAS_MINIMUM, tRAS_MAXIMUM, tRAS_MINIMUM, tRAS_MAXIMUM};
+
+static GACI_DATA tRPGaciData = {BIOS_TRP_IMPLEMENTATION,\
+ tRP_NumOfValues, 0, 0, 0, tRP_MINIMUM, tRP_MAXIMUM, tRP_MINIMUM, tRP_MAXIMUM};
+
+static GACI_DATA tRCDGaciData = {BIOS_TRCD_IMPLEMENTATION,\
+ tRCD_NumOfValues, 0, 0, 0, tRCD_MINIMUM, tRCD_MAXIMUM, tRCD_MINIMUM, tRCD_MAXIMUM};
+
+static GACI_DATA tWRGaciData = {BIOS_TWR_IMPLEMENTATION,\
+ tWR_NumOfValues, 0, 0, 0, tWR_MINIMUM, tWR_MAXIMUM, tWR_MINIMUM, tWR_MAXIMUM};
+
+static GACI_DATA tRFCGaciData = {BIOS_TRFC_IMPLEMENTATION,\
+ tRFC_NumOfValues, 0, 0, 0, tRFC_MINIMUM, tRFC_MAXIMUM, tRFC_MINIMUM, tRFC_MAXIMUM};
+
+static GACI_DATA tRRDGaciData = {BIOS_TRRD_IMPLEMENTATION,\
+ tRRD_NumOfValues, 0, 0, 0, tRRD_MINIMUM, tRRD_MAXIMUM, tRRD_MINIMUM, tRRD_MAXIMUM};
+
+static GACI_DATA tWTRGaciData = {BIOS_TWTR_IMPLEMENTATION,\
+ tWTR_NumOfValues, 0, 0, 0, tWTR_MINIMUM, tWTR_MAXIMUM, tWTR_MINIMUM, tWTR_MAXIMUM};
+
+static GACI_DATA tRTPGaciData = {BIOS_TRTP_IMPLEMENTATION,\
+ tRTP_NumOfValues, 0, 0, 0, tRTP_MINIMUM, tRTP_MAXIMUM, tRTP_MINIMUM, tRTP_MAXIMUM};
+
+static GACI_DATA tFAWGaciData = {BIOS_TFAW_IMPLEMENTATION,\
+ tFAW_NumOfValues, 0, 0, 0, tFAW_MINIMUM, tFAW_MAXIMUM, tFAW_MINIMUM, tFAW_MAXIMUM};
+
+static GACI_DATA tRCGaciData = {BIOS_TRC_IMPLEMENTATION,\
+ tRC_NumOfValues, 0, 0, 0, tRC_MINIMUM, tRC_MAXIMUM, tRC_MINIMUM, tRC_MAXIMUM};
+
+//static GACI_DATA tRPabGaciData = {BIOS_TRPAB_IMPLEMENTATION,\
+// tRPab_NumOfValues, 0, 0, 0, tRPab_MINIMUM, tRPab_MAXIMUM, tRPab_MINIMUM, tRPab_MAXIMUM};
+
+static GACI_DATA DramMultiGaciData = {BIOS_DDR_MULT_IMPLEMENTATION,\
+ 0xFFFF, 2, 0, 0, 0, 0, 0, 0};
+
+static GACI_DATA XmpProfSelData = {BIOS_XMP_PROFILE_SELECTION_IMPLEMENTATION,\
+ 3, 0, 0, 0, 0, 3, 0, 3};
+
+static GACI_DATA CpuRuntimeTurbo = {BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION,\
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+static GACI_DATA iGfxTurboRatioData = {BIOS_GRAPHICS_TURBO_RATIO_LIMIT_IMPLEMENTATION,\
+ iGfxRatio_NumOfValues, 1, 0, 0, 0, iGfxRatio_MAXIMUM, 0, iGfxRatio_MAXIMUM};
+
+//static GACI_DATA iGfxVoltageData = {BIOS_GRAPHICS_CORE_VOLTAGE_IMPLEMENTATION,\
+// iGfxVolt_NumOfValues, 0, 0, 0, iGfxVolt_MINIMUM, iGfxVolt_MAXIMUM, iGfxVolt_MINIMUM, iGfxVolt_MAXIMUM};
+
+static GACI_DATA iGfxVoltageOverride = {BIOS_GRAPHICS_CORE_VOLTAGE_OVERRIDE_IMPLEMENTATION,\
+ iGfxVoltOverride_NumOfValues, 3, 0, 0, iGfxVoltOverride_MINIMUM, iGfxVoltOverride_MAXIMUM, iGfxVoltOverride_MINIMUM, iGfxVoltOverride_MAXIMUM};
+
+static GACI_DATA iGfxVoltageMode = {BIOS_GRAPHICS_CORE_VOLTAGE_MODE_IMPLEMENTATION,\
+ 1, 0, 0, 0, 0, 1, 0, 1};
+
+static GACI_DATA iGfxVoltageOffset = {BIOS_GRAPHICS_CORE_VOLTAGE_OFFSET_IMPLEMENTATION,\
+ 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+static GACI_DATA SaVoltageOffset = {BIOS_SYSTEM_AGENT_VOLTAGE_OFFSET_IMPLEMENTATION,\
+ 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+static GACI_DATA IoaVoltageOffset = {BIOS_IO_ANALOG_VOLTAGE_OFFSET_IMPLEMENTATION,\
+ 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+static GACI_DATA IodVoltageOffset = {BIOS_IO_DIGITAL_VOLTAGE_OFFSET_IMPLEMENTATION,\
+ 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+static GACI_DATA MemClockMultiplier = {BIOS_MEM_CLOCK_MULTIPLIER_IMPLEMENTATION,\
+ 0xFFFF, 2, 0, 0, 0, 0, 0, 0};
+
+//========================================== XMP Profile TABLE ======================================================
+//Profile 1 data
+// GXDV DevNameGxdvData = {ControlID, Reserved, Precision, DisplayValue};
+static GXDV_DATA Pro1tCLGxdvData = {BIOS_TCL_IMPLEMENTATION, 0, 0, 8};
+static GXDV_DATA Pro1tRASGxdvData = {BIOS_TRAS_IMPLEMENTATION, 0, 0, 23};
+static GXDV_DATA Pro1tRPGxdvData = {BIOS_TRP_IMPLEMENTATION, 0, 0, 8};
+static GXDV_DATA Pro1tRCDGxdvData = {BIOS_TRCD_IMPLEMENTATION, 0, 0, 8};
+static GXDV_DATA Pro1tWRGxdvData = {BIOS_TWR_IMPLEMENTATION, 0, 0, 9};
+static GXDV_DATA Pro1tRFCGxdvData = {BIOS_TRFC_IMPLEMENTATION, 0, 0, 73};
+static GXDV_DATA Pro1tRRDGxdvData = {BIOS_TRRD_IMPLEMENTATION, 0, 0, 4};
+static GXDV_DATA Pro1tWTRGxdvData = {BIOS_TWTR_IMPLEMENTATION, 0, 0, 5};
+static GXDV_DATA Pro1tRTPGxdvData = {BIOS_TRTP_IMPLEMENTATION, 0, 0, 5};
+static GXDV_DATA Pro1tFAWGxdvData = {BIOS_TFAW_IMPLEMENTATION, 0, 0, 20};
+static GXDV_DATA Pro1tRCGxdvData = {BIOS_TRC_IMPLEMENTATION, 0, 0, 20};
+static GXDV_DATA Pro1tREFIGxdvData = {BIOS_TREFI_IMPLEMENTATION, 0, 0, 1000};
+static GXDV_DATA Pro1tCWLGxdvData = {BIOS_TCWL_IMPLEMENTATION, 0, 0, 8};
+//static GXDV_DATA Pro1tRPabGxdvData = {BIOS_TRPAB_IMPLEMENTATION, 0, 0, 4};
+static GXDV_DATA Pro1DdrMulGxdvData = {BIOS_DDR_MULT_IMPLEMENTATION, 0, 0, 16};
+static GXDV_DATA Pro1DdrClkMulGxdvData = {BIOS_MEM_CLOCK_MULTIPLIER_IMPLEMENTATION, 0,2, 133};
+
+//profile 2 data
+// GXDV DevNameGxdvData = {ControlID, Reserved, Precision, DisplayValue};
+static GXDV_DATA Pro2tCLGxdvData = {BIOS_TCL_IMPLEMENTATION, 0, 0, 7};
+static GXDV_DATA Pro2tRASGxdvData = {BIOS_TRAS_IMPLEMENTATION, 0, 0, 22};
+static GXDV_DATA Pro2tRPGxdvData = {BIOS_TRP_IMPLEMENTATION, 0, 0, 7};
+static GXDV_DATA Pro2tRCDGxdvData = {BIOS_TRCD_IMPLEMENTATION, 0, 0, 7};
+static GXDV_DATA Pro2tWRGxdvData = {BIOS_TWR_IMPLEMENTATION, 0, 0, 8};
+static GXDV_DATA Pro2tRFCGxdvData = {BIOS_TRFC_IMPLEMENTATION, 0, 0, 72};
+static GXDV_DATA Pro2tRRDGxdvData = {BIOS_TRRD_IMPLEMENTATION, 0, 0, 4};
+static GXDV_DATA Pro2tWTRGxdvData = {BIOS_TWTR_IMPLEMENTATION, 0, 0, 5};
+static GXDV_DATA Pro2tRTPGxdvData = {BIOS_TRTP_IMPLEMENTATION, 0, 0, 5};
+static GXDV_DATA Pro2tFAWGxdvData = {BIOS_TFAW_IMPLEMENTATION, 0, 0, 20};
+static GXDV_DATA Pro2tRCGxdvData = {BIOS_TRC_IMPLEMENTATION, 0, 0, 20};
+static GXDV_DATA Pro2tREFIGxdvData = {BIOS_TREFI_IMPLEMENTATION, 0, 0, 1000};
+static GXDV_DATA Pro2tCWLGxdvData = {BIOS_TCWL_IMPLEMENTATION, 0, 0, 8};
+//static GXDV_DATA Pro2tRPabGxdvData = {BIOS_TRPAB_IMPLEMENTATION, 0, 0, 4};
+static GXDV_DATA Pro2DdrMulGxdvData = {BIOS_DDR_MULT_IMPLEMENTATION, 0, 0, 18};
+static GXDV_DATA Pro2DdrClkMulGxdvData = {BIOS_MEM_CLOCK_MULTIPLIER_IMPLEMENTATION, 0,2, 133};
+//===================================================================================================================
+
+
+static
+MrcFrequency
+NbGetDimmFrequency (
+ IN UINT32 tCK
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetIGDSettings
+//
+// Description: Update XTU GACI Table function .
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetIGDSettings(void)
+{
+ UINT32 GTTMMADR;// = 0xF7800000;
+ UINT32 Data32;
+
+ //
+ // Program GT PM Settings if GTTMMADR allocation is Successful
+ //
+ GTTMMADR = (UINT32)NB_TEMP_MMIO_BASE;
+ WRITE_PCI32_IGD (R_SA_IGD_GTTMMADR, (GTTMMADR | BIT02)); // 0x10
+
+ //
+ // Enable Bus Master, I/O and Memory access on 0:2:0
+ //
+ SET_PCI8_IGD (R_SA_IGD_CMD , (BIT02 | BIT01)); // 0x04
+
+ TRACE((-1,"GT Overclocking Support is enabled in BIOS Setup\n"));
+
+ //
+ // Wait for Mailbox ready
+ //
+ while (READ_MEM32 ((UINTN)(GTTMMADR + 0x138124)) & BIT31) {
+ Data32 = READ_MEM32 ((UINTN)(GTTMMADR + 0x138124));
+ };
+
+ //
+ // Mailbox Command - MAILBOX_GTDRIVER_CMD_READ_OVERCLOCK_PARAMS to READ OC SUPPORT
+ //
+ Data32 = 0x8000000C;
+ WRITE_MEM32 ((UINTN)(GTTMMADR + 0x138124), Data32);
+
+ //
+ // Wait for Mailbox ready
+ //
+ while (READ_MEM32 ((UINTN)(GTTMMADR + 0x138124)) & BIT31) {
+ Data32 = READ_MEM32 ((UINTN)(GTTMMADR + 0x138124));
+ };
+
+
+ if (READ_MEM32 ((UINTN)(GTTMMADR + 0x138128)) & BIT31)
+ {
+ Data32 = READ_MEM32 ((UINTN)(GTTMMADR + 0x138128));
+ return Data32;
+ }
+ return Data32;
+}
+
+EFI_STATUS GetDddtPresentFlagHob()
+{
+ EFI_STATUS Status;
+ EFI_GUID gDddtPreFlagHobGuid = AMI_DDDT_PRESENT_FLAG_HOB_GUID;
+ VOID *gDddtPreFlagHobList = NULL;
+ UINTN FlagCount = (sizeof(BIOS_SETTING_DATA) - sizeof(BIOS_SETTING_HDR))/sizeof(UINT16);
+
+// Get Hob List
+ gDddtPreFlagHobList = GetEfiConfigurationTable(pST, &gHobListGuid);
+ if (!gDddtPreFlagHobList) return EFI_NOT_FOUND;
+
+// Find CPUID Checksum Data Hob.
+ gDddtPresentFlagHob = (DDDT_PRESENT_FLAG_HOB*)gDddtPreFlagHobList;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &gDddtPresentFlagHob)))
+ {
+ if (guidcmp(&gDddtPresentFlagHob->EfiHobGuidType.Name, &gDddtPreFlagHobGuid) == 0)
+ break;
+ }
+
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+ return Status;
+}
+
+typedef union _OC_MAILBOX_INTERFACE {
+ UINT32 InterfaceData;
+ struct {
+ UINT8 CommandCompletion:8;
+ UINT8 Param1:8;
+ UINT8 Param2:8;
+ UINT8 Reserved:7;
+ UINT8 RunBusy:1;
+ } Fields;
+} OC_MAILBOX_INTERFACE;
+
+typedef struct _OC_MAILBOX_FULL {
+ UINT32 Data;
+ OC_MAILBOX_INTERFACE Interface;
+} OC_MAILBOX_FULL;
+
+typedef struct {
+ UINT8 MaxOcRatio;
+ UINT8 VoltageTargetMode;
+ UINT16 VoltageTarget;
+ INT16 VoltageOffset;
+} VOLTAGE_FREQUENCY_SETTINGS;
+
+typedef struct {
+ VOLTAGE_FREQUENCY_SETTINGS VfSettings;
+ UINT8 DomainId;
+} VOLTAGE_FREQUENCY_ITEM;
+
+typedef struct {
+ UINT8 MaxOcRatioLimit;
+ BOOLEAN RatioOcSupported;
+ BOOLEAN VoltageOverridesSupported;
+ BOOLEAN VoltageOffsetSupported;
+ UINT8 DomainId;
+} OC_CAPABILITIES_ITEM;
+
+typedef union _OC_MAILBOX_COMMAND {
+ UINT32 InterfaceData;
+ struct {
+ UINT8 CommandCompletion:8;
+ UINT8 Param1:8;
+ UINT8 Param2:8;
+ UINT8 Reserved:7;
+ UINT8 RunBusy:1;
+ } Fields;
+} OC_MAILBOX_COMMAND;
+
+typedef struct _OC_MAILBOX_ITEM {
+ UINT32 Data;
+ OC_MAILBOX_COMMAND Interface;
+} OC_MAILBOX_ITEM;
+
+
+EFI_STATUS
+EFIAPI PollOcMailboxReady (
+ )
+/**
+
+ Poll the run/busy bit of the mailbox until available or timeout expires.
+
+ @param[IN] MailboxType,
+
+ @retval EFI_STATUS
+
+**/
+{
+ EFI_STATUS Status;
+ UINT16 StallCount;
+ UINT8 RunBusyBit;
+ UINT64 MsrData;
+ OC_MAILBOX_FULL OcMailboxFull;
+
+ Status = EFI_SUCCESS;
+ StallCount = 0;
+ RunBusyBit = 1;
+
+ do {
+// case MAILBOX_TYPE_OC:
+ ///
+ /// Read the OC mailbox run/busy state
+ ///
+ MsrData = ReadMsr(OC_MAILBOX_MSR);
+ pBS->CopyMem (&OcMailboxFull.Data, &MsrData, sizeof(OcMailboxFull));
+ RunBusyBit = OcMailboxFull.Interface.Fields.RunBusy;
+// break;
+ //
+ // Wait for 1us
+ //
+ CountTime(4, PM_BASE_ADDRESS);
+ StallCount++;
+ }
+ while ((RunBusyBit == 1) && (StallCount < MAILBOX_WAIT_TIMEOUT));
+
+ if ((RunBusyBit == 0) && (StallCount == MAILBOX_WAIT_TIMEOUT)) {
+ TRACE ((TRACE_ALWAYS, "(MAILBOX) Mailbox interface timed out.\n"));
+ Status = EFI_TIMEOUT;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI OcMailboxRead (
+ IN UINT32 MailboxCommand,
+ OUT UINT32 *MailboxDataPtr,
+ OUT UINT32 *MailboxStatus
+
+ )
+/**
+
+ Generic Mailbox function for mailbox read commands. This function will write
+ the read request, and populate the read results in the output data.
+
+ @param[IN] MailboxType,
+ @param[IN] MailboxCommand,
+ @param[OUT] *MailboxDataPtr,
+ @param[OUT] *MailboxStatus
+
+ @retval EFI_STATUS
+
+**/
+{
+ EFI_STATUS Status;
+ UINT64 MsrData;
+ OC_MAILBOX_FULL OcMailboxFull;
+ OC_MAILBOX_FULL OcMailboxFullVerify;
+
+ ///
+ /// Poll the run/busy to ensure the interface is available
+ ///
+ Status = PollOcMailboxReady();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ TRACE ((TRACE_ALWAYS, "(MAILBOX) Mailbox Read Command = %2X\n", (UINT8)MailboxCommand));
+
+ // MAILBOX_TYPE_OC:
+ ///
+ /// Set the Run/Busy bit to signal mailbox data is ready to process
+ ///
+ OcMailboxFull.Interface.InterfaceData = MailboxCommand;
+ OcMailboxFull.Data = *MailboxDataPtr;
+ OcMailboxFull.Interface.Fields.RunBusy = 1;
+ pBS->CopyMem (&MsrData, &OcMailboxFull, sizeof(MsrData));
+
+ ///
+ /// Write mailbox command to OC mailbox
+ ///
+ WriteMsr (OC_MAILBOX_MSR, MsrData);
+
+ ///
+ /// Poll run/busy to indicate the completion of write request
+ ///
+ PollOcMailboxReady();
+
+ ///
+ /// Read the OC mailbox to verify read completion success.
+ /// Mailbox protocol requires software to read back the interface twice
+ /// to ensure the read results are consistent.
+ ///
+ MsrData = ReadMsr (OC_MAILBOX_MSR);
+ pBS->CopyMem (&OcMailboxFull, &MsrData, sizeof(OcMailboxFull));
+
+ CountTime(40000, PM_BASE_ADDRESS); // 10ms
+
+ MsrData = ReadMsr (OC_MAILBOX_MSR);
+ pBS->CopyMem (&OcMailboxFullVerify, &MsrData, sizeof(OcMailboxFullVerify));
+
+ ///
+ /// If the data is inconsistent, we cannot trust the results
+ ///
+ if (OcMailboxFull.Interface.InterfaceData != OcMailboxFullVerify.Interface.InterfaceData ){
+ if (OcMailboxFull.Data != OcMailboxFullVerify.Data) {
+ TRACE ((TRACE_ALWAYS, "(MAILBOX) Mailbox read data is corrupted.\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ ///
+ /// Copy Overclocking mailbox completion code and read results
+ ///
+ *MailboxStatus = OcMailboxFull.Interface.Fields.CommandCompletion;
+ pBS->CopyMem(MailboxDataPtr, &OcMailboxFull.Data, sizeof(UINT32));
+
+
+ TRACE ((TRACE_ALWAYS, "(MAILBOX) Mailbox Status = %2X\n", *MailboxStatus));
+
+ return Status;
+}
+
+VOID
+ConvertVoltageTarget (
+ IN UINT16 InputVoltageTarget,
+ OUT UINT16* OutputVoltageTarget,
+ IN UINT8 ConversionType
+ )
+/**
+
+ Converts the input voltage target to the fixed point U12.2.10 Volt format or
+ the Binary millivolts representation based on the ConversionType
+
+@param[IN] InputVoltageTarget
+@param[OUT] *OutputVoltageTarget
+@param[IN] ConversionType - 0:fixed point, 1:Binary millivolts
+
+**/
+{
+ /// Fixed point representation:
+ ///
+ /// U12.2.10V format
+ /// | | | |
+ /// | | | v
+ /// | | v Exponent
+ /// | v Significand Size
+ /// v Size
+ /// Signed/Unsigned
+ ///
+ /// Float Value = Significand x (Base ^ Exponent)
+ /// (Base ^ Exponent) = 2 ^ 10 = 1024
+ ///
+
+ if (InputVoltageTarget == 0){
+ *OutputVoltageTarget = 0;
+ return;
+ }
+
+ if(ConversionType == CONVERT_TO_FIXED_POINT_VOLTS){
+ ///
+ /// Input Voltage is in number of millivolts. Clip the input Voltage
+ /// to the max allowed by the fixed point format
+ ///
+ if (InputVoltageTarget > MAX_TARGET_MV)
+ InputVoltageTarget = MAX_TARGET_MV;
+
+ ///
+ /// InputTargetVoltage is the significand in mV. Need to convert to Volts
+ ///
+ *OutputVoltageTarget = (InputVoltageTarget * 1024)/ MILLIVOLTS_PER_VOLT;
+
+ }
+ else if (ConversionType == CONVERT_TO_BINARY_MILLIVOLT){
+ ///
+ /// InputVoltage is specified in fixed point representation, need to
+ /// convert to millivolts
+ ///
+ *OutputVoltageTarget = (InputVoltageTarget * MILLIVOLTS_PER_VOLT)/1024;
+ }
+
+ return;
+}
+
+VOID
+ConvertVoltageOffset (
+ IN INT16 InputVoltageOffset,
+ OUT INT16* OutputVoltageOffset,
+ IN UINT8 ConversionType
+ )
+/**
+
+ Converts the input votlage Offset to the fixed point S11.0.10 Volt format or
+ to Binary illivolts representation based on the ConversionType.
+
+@param[IN] InputVoltageTarget
+@param[OUT] *OutputVoltageTarget
+@param[IN] ConversionType - 0:fixed point, 1:Signed Binary millivolts
+
+
+**/
+{
+ BOOLEAN NumIsNegative;
+ /// Fixed point representation:
+ ///
+ /// S11.0.10V format
+ /// | | | |
+ /// | | | v
+ /// | | v Exponent
+ /// | v Significand Size
+ /// v Size
+ /// Signed/Unsigned
+ ///
+ /// Float Value = Significand x (Base ^ Exponent)
+ /// (Base ^ Exponent) = 2 ^ 10 = 1024
+ ///
+ *OutputVoltageOffset = 0;
+ NumIsNegative = FALSE;
+
+ if (InputVoltageOffset == 0){
+ *OutputVoltageOffset = 0;
+ return;
+ }
+
+ if (ConversionType == CONVERT_TO_FIXED_POINT_VOLTS){
+ ///
+ /// Input Voltage is in INT16 representation. Check if numenr is negative
+ ///
+ if ( (InputVoltageOffset & INT16_SIGN_BIT_MASK) != 0){
+ NumIsNegative = TRUE;
+ ///
+ /// Need to 2's complement adjust to make this number positive for
+ /// voltage calculation
+ ///
+ InputVoltageOffset = (~InputVoltageOffset+1) & (INT16_SIGN_BIT_MASK -1);
+ }
+
+ ///
+ /// Clip the input Voltage Offset to 500mv
+ ///
+ if (InputVoltageOffset > MAX_OFFSET_MV) {
+ InputVoltageOffset = MAX_OFFSET_MV;
+ }
+
+ ///
+ /// Convert to fixed point representation
+ ///
+ *OutputVoltageOffset = (InputVoltageOffset * 1024)/ MILLIVOLTS_PER_VOLT;
+ if (NumIsNegative){
+ /// 2's complement back to a negative number
+ *OutputVoltageOffset = ~(*OutputVoltageOffset) + 1;
+ }
+ }
+ else if (ConversionType == CONVERT_TO_BINARY_MILLIVOLT){
+ ///
+ /// Input Voltage is in fixed point representation. Check if number negative
+ ///
+ if( (InputVoltageOffset & FIXED_POINT_SIGN_BIT_MASK)!= 0){
+ NumIsNegative = TRUE;
+ ///
+ /// Need to 2's complement adjust to make this number positive for
+ /// voltage calculation
+ ///
+ InputVoltageOffset = (~InputVoltageOffset+1) & (FIXED_POINT_SIGN_BIT_MASK -1);
+ }
+
+ ///
+ /// Convert to INT16 representation in millivolts
+ ///
+ *OutputVoltageOffset = (InputVoltageOffset * MILLIVOLTS_PER_VOLT)/1024;
+ if (NumIsNegative){
+ /// 2's complement back to a negative number
+ *OutputVoltageOffset = ~(*OutputVoltageOffset) + 1;
+ }
+ }
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI GetOcCapabilities (
+ OUT OC_CAPABILITIES_ITEM *OcCapabilities,
+ OUT UINT32 *LibStatus
+ )
+/**
+ Get the overclocking capabilities for a given CPU Domain
+
+ @param[OUT] *OcCapabilities
+ @param[OUT] *LibStatus
+
+ @retval EFI_STATUS
+**/
+{
+ EFI_STATUS Status;
+ UINT32 CommandId;
+ OC_MAILBOX_ITEM OcCapsMsg;
+
+ Status = EFI_SUCCESS;
+
+// ZeroMem(&OcCapsMsg,sizeof(OC_MAILBOX_ITEM));
+
+ ///
+ /// Convert OC capabilties message to Mailbox command format
+ ///
+ CommandId = OC_LIB_CMD_GET_OC_CAPABILITIES;
+ //ConvertToMailboxFormat((VOID *)OcCapabilities, &OcCapsMsg, CommandId);
+ OcCapsMsg.Data = 0;
+ OcCapsMsg.Interface.Fields.CommandCompletion = CommandId;
+ OcCapsMsg.Interface.Fields.Param1 = 1;
+ ///
+ /// Read From the OC Library
+ ///
+ Status = OcMailboxRead(OcCapsMsg.Interface.InterfaceData, &OcCapsMsg.Data, LibStatus);
+
+ ///
+ /// Copy mailbox data to OC Capabilities structure
+ ///
+ if ( (Status == EFI_SUCCESS) && (*LibStatus == OC_LIB_COMPLETION_CODE_SUCCESS)) {
+ OcCapabilities->MaxOcRatioLimit =
+ (UINT8) OcCapsMsg.Data & OC_CAPS_MAX_RATIO_MASK;
+
+ OcCapabilities->RatioOcSupported =
+ (UINT8) ((OcCapsMsg.Data & OC_CAPS_RATIO_SUPPORT_MASK) >> OC_CAPS_RATIO_SUPPORT_OFFSET);
+
+ OcCapabilities->VoltageOverridesSupported =
+ (UINT8) ((OcCapsMsg.Data & OC_CAPS_OVERRIDE_SUPPORT_MASK) >> OC_CAPS_OVERRIDE_SUPPORT_OFFSET);
+
+ OcCapabilities->VoltageOffsetSupported =
+ (UINT8) ((OcCapsMsg.Data & OC_CAPS_OFFSET_SUPPORT_MASK) >> OC_CAPS_OFFSET_SUPPORT_OFFSET);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI GetVoltageFrequencyItem (
+ OUT VOLTAGE_FREQUENCY_ITEM * VfSettings,
+ OUT UINT32 *LibStatus
+ )
+/**
+
+ Gets the Voltage and Frequency information for a given CPU domain
+
+ @param[OUT] *VfSettings
+ @param[OUT] *LibStatus
+
+ @retval EFI_STATUS
+
+**/
+{
+ EFI_STATUS Status;
+ UINT32 CommandId;
+ UINT16 TempVoltageTarget;
+ INT16 TempVoltageOffset;
+ OC_MAILBOX_ITEM VfMsg;
+
+ Status = EFI_SUCCESS;
+
+ ///
+ /// Convert v/f command to Mailbox command format
+ ///
+ CommandId = OC_LIB_CMD_GET_VOLTAGE_FREQUENCY;
+
+// ConvertToMailboxFormat((VOID*)VfSettings, &VfMsg, CommandId);
+
+ ///
+ /// Voltage Frequency Settings are on a per domain basis
+ ///
+ VfMsg.Data = 0;
+ VfMsg.Interface.Fields.CommandCompletion = CommandId;
+ VfMsg.Interface.Fields.Param1 = 1;
+
+ ///
+ /// Read From the OC Library
+ ///
+ Status = OcMailboxRead(VfMsg.Interface.InterfaceData, &VfMsg.Data, LibStatus);
+
+ ///
+ /// Copy mailbox data to VfSettings
+ ///
+ if ( (Status == EFI_SUCCESS) && (*LibStatus == OC_LIB_COMPLETION_CODE_SUCCESS)){
+ VfSettings->VfSettings.MaxOcRatio = (UINT8) (VfMsg.Data & MAX_RATIO_MASK);
+ VfSettings->VfSettings.VoltageTargetMode = (UINT8) ( (VfMsg.Data & VOLTAGE_MODE_MASK) >> VOLTAGE_MODE_OFFSET);
+
+ TempVoltageTarget = (UINT16) (VfMsg.Data & VOLTAGE_TARGET_MASK) >> VOLTAGE_TARGET_OFFSET;
+ ConvertVoltageTarget(TempVoltageTarget, &VfSettings->VfSettings.VoltageTarget, CONVERT_TO_BINARY_MILLIVOLT);
+
+ TempVoltageOffset = (INT16)((VfMsg.Data & VOLTAGE_OFFSET_MASK) >> VOLTAGE_OFFSET_OFFSET);
+ ConvertVoltageOffset(TempVoltageOffset, &VfSettings->VfSettings.VoltageOffset, CONVERT_TO_BINARY_MILLIVOLT);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NbXTUSetGACITable
+//
+// Description: Update XTU GACI Table function .
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NbXTUSetGACITable(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT8 *Buffer = NULL;
+ UINTN Len = 0;
+ UINT8 channel = 0;
+ EFI_GUID gXtuDataHobGuid = AMI_PERF_TUNE_DATA_HOB_GUID;
+ UINT8 NumOcBins = (UINT8)(ReadMsr(0x194) >> 17) & 0x7;
+ VOID *FirstHob;
+ AMI_INTERNAL_FACTORY_TDC_TDP_HOB *TdcTdpHob = NULL;
+ BOOLEAN TdcTdpHobFound = FALSE, OcDataHobFound = FALSE;
+ UINT16 OneCoreRatioLimit;
+ UINT16 MaxNonTurboRatio;
+ UINT8 MemRatio, RefClkRatio;
+ UINT32 CurrentRatio;
+ OC_CAPABILITIES_ITEM OcCaps;
+ UINT32 LibStatus;
+ PERF_TUNE_DATA_HOB *PerfTuneDataHob = NULL;
+ UINT32 MemFreq;
+ MrcFrequency DDRFrequency[2] = {fNoInit};
+
+ if (gPerfTuneAslProtocol == NULL)
+ {
+ Status = pBS->LocateProtocol(&gPerfTuneAslProtocolGuid, NULL, &gPerfTuneAslProtocol);
+ if(EFI_ERROR(Status))goto Done;
+ }
+
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+
+ TdcTdpHob = (AMI_INTERNAL_FACTORY_TDC_TDP_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &TdcTdpHob))) {
+ if (guidcmp(&TdcTdpHob->EfiHobGuidType.Name, &gAmiInternalFactoryTdcTdpHobGuid) == 0) {
+ TdcTdpHobFound = TRUE;
+ break;
+ }
+ }
+
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+
+ PerfTuneDataHob = (PERF_TUNE_DATA_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &PerfTuneDataHob))) {
+ if (guidcmp(&PerfTuneDataHob->EfiHobGuidType.Name, &gXtuDataHobGuid) == 0) {
+ OcDataHobFound = TRUE;
+ break;
+ }
+ }
+
+//========================== GACI TABLE =============================================
+//------------------------- tCL Setting ----------------------------------------
+ Len = sizeof(tCLGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tCLGaciData.DefaultDataValue = NBMrcTimingData[0].tCL;//DefaultData.tCL;
+
+ MemCpy(Buffer, &tCLGaciData, sizeof(tCLGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tCL);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tCWL Setting ---------------------------------------
+ Len = sizeof(tCWLGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tCWLGaciData.DefaultDataValue = NBMrcTimingData[0].tCWL;//DefaultData.tCWL;
+
+ MemCpy(Buffer, &tCWLGaciData, sizeof(tCWLGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tCWL);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tREFI Setting ---------------------------------------
+ Len = sizeof(tREFIGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tREFIGaciData.DefaultDataValue = NBMrcTimingData[0].tREFI;//DefaultData.tREFI;
+
+ MemCpy(Buffer, &tREFIGaciData, sizeof(tREFIGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tREFI);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRCD Setting ---------------------------------------
+ Len = sizeof(tRCDGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRCDGaciData.DefaultDataValue = NBMrcTimingData[0].tRCD;//DefaultData.tRCD;
+
+ MemCpy(Buffer, &tRCDGaciData, sizeof(tRCDGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRCD);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRP Setting ----------------------------------------
+ Len = sizeof(tRPGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRPGaciData.DefaultDataValue = NBMrcTimingData[0].tRP;//DefaultData.tRP;
+
+ MemCpy(Buffer, &tRPGaciData, sizeof(tRPGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRP);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRAS Setting ---------------------------------------
+ Len = sizeof(tRASGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRASGaciData.DefaultDataValue = NBMrcTimingData[0].tRAS;//DefaultData.tRAS;
+
+ MemCpy(Buffer, &tRASGaciData, sizeof(tRASGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRAS);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tWR Setting ---------------------------------------
+ Len = sizeof(tWRGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tWRGaciData.DefaultDataValue = NBMrcTimingData[0].tWR;//DefaultData.tWR;
+
+ MemCpy(Buffer, &tWRGaciData, sizeof(tWRGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tWR);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRFC Setting ---------------------------------------
+ Len = sizeof(tRFCGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRFCGaciData.DefaultDataValue = NBMrcTimingData[0].tRFC;//DefaultData.tRFC;
+
+ MemCpy(Buffer, &tRFCGaciData, sizeof(tRFCGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRFC);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRRD Setting ---------------------------------------
+ Len = sizeof(tRRDGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+ tRRDGaciData.DefaultDataValue = NBMrcTimingData[0].tRRD;//DefaultData.tRRD;
+
+ MemCpy(Buffer, &tRRDGaciData, sizeof(tRRDGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRRD);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tWTR Setting ---------------------------------------
+ Len = sizeof(tWTRGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tWTRGaciData.DefaultDataValue = NBMrcTimingData[0].tWTR;//DefaultData.tWTR;
+
+ MemCpy(Buffer, &tWTRGaciData, sizeof(tWTRGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tWTR);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRTP Setting ---------------------------------------
+ Len = sizeof(tRTPGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRTPGaciData.DefaultDataValue = NBMrcTimingData[0].tRTP;//DefaultData.tRTP;
+
+ MemCpy(Buffer, &tRTPGaciData, sizeof(tRTPGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRTP);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tFAW Setting ---------------------------------------
+ Len = sizeof(tFAWGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tFAWGaciData.DefaultDataValue = NBMrcTimingData[0].tFAW;//DefaultData.tFAW;
+
+ MemCpy(Buffer, &tFAWGaciData, sizeof(tFAWGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tFAW);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRC Setting ---------------------------------------
+ Len = sizeof(tRCGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ tRCGaciData.DefaultDataValue = NBMrcTimingData[0].tRC;//DefaultData.tRC;
+
+ MemCpy(Buffer, &tRCGaciData, sizeof(tRCGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRC);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------- tRPab Setting ---------------------------------------
+// Len = sizeof(tRPabGaciData);
+// Buffer = MallocZ(Len);
+// if(!Buffer) goto Done;
+
+// tRPabGaciData.DefaultDataValue = NBMrcTimingData[0].tRPab;//DefaultData.tRPab;
+
+// MemCpy(Buffer, &tRPabGaciData, sizeof(tRPabGaciData));
+// Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)NBMrcTimingData[MemoryProfile].tRPab);
+// Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+// pBS->FreePool(Buffer);
+//----------------------------- iGfX Core Ratio Limit ---------------------------
+ if (READ_PCI32_IGD (R_SA_IGD_VID) != 0xFFFFFFFF) {
+
+ Status = GetOcCapabilities(&OcCaps,&LibStatus);
+ if ( (Status == EFI_SUCCESS) && (LibStatus == OC_LIB_COMPLETION_CODE_SUCCESS)) {
+
+ Len = sizeof(iGfxTurboRatioData);
+ Buffer = MallocZ(Len);
+
+
+ CurrentRatio = OcCaps.MaxOcRatioLimit;
+
+ iGfxTurboRatioData.MinDataValue = READ_MEM8_MCH(0x5998); // Rpm
+ iGfxTurboRatioData.MaxDataValue = CurrentRatio;
+ iGfxTurboRatioData.DefaultDataValue = READ_MEM8_MCH(0x5998); // Rpm
+
+
+ iGfxTurboRatioData.MinDisplayValue = iGfxTurboRatioData.MinDataValue * 5;
+ iGfxTurboRatioData.MaxDisplayValue = iGfxTurboRatioData.MaxDataValue * 5;
+ iGfxTurboRatioData.NumberOfValues = iGfxTurboRatioData.MaxDataValue - iGfxTurboRatioData.MinDataValue + 1;
+
+
+ MemCpy(Buffer, &iGfxTurboRatioData, sizeof(iGfxTurboRatioData));
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------------- iGfX Voltage mode -------------------------------
+ Len = sizeof(iGfxVoltageMode);
+ Buffer = MallocZ(Len);
+
+ iGfxVoltageMode.MaxDataValue = 1;
+ iGfxVoltageMode.MaxDisplayValue = 1;
+ iGfxVoltageMode.NumberOfValues = 2;
+
+ MemCpy(Buffer, &iGfxVoltageMode, sizeof(iGfxVoltageMode));
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------------- iGfX Voltage -------------------------------
+// Len = sizeof(iGfxVoltageData);
+// Buffer = MallocZ(Len);
+
+ //GtOcVolt = CurrentVfItem.VfSettings.VoltageTarget;
+
+// MemCpy(Buffer, &iGfxVoltageData, sizeof(iGfxVoltageData));
+
+ //Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)GtOcVolt);
+
+// Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+// pBS->FreePool(Buffer);
+//------------------------------- iGfX Voltage Override-------------------------------
+ Len = sizeof(iGfxVoltageOverride);
+ Buffer = MallocZ(Len);
+
+
+ MemCpy(Buffer, &iGfxVoltageOverride, sizeof(iGfxVoltageOverride));
+
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//------------------------------- iGfX Voltage Offset-------------------------------
+ Len = sizeof(iGfxVoltageOffset);
+ Buffer = MallocZ(Len);
+
+
+ MemCpy(Buffer, &iGfxVoltageOffset, sizeof(iGfxVoltageOffset));
+
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+ } // GetVoltageFrequencyItem
+ } // if have IGFX ?
+//------------------------------- Sa Voltage Offset -------------------------------
+ Len = sizeof(SaVoltageOffset);
+ Buffer = MallocZ(Len);
+
+ MemCpy(Buffer, &SaVoltageOffset, sizeof(SaVoltageOffset));
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//------------------------------- IOA Voltage Offset -------------------------------
+ Len = sizeof(IoaVoltageOffset);
+ Buffer = MallocZ(Len);
+
+ MemCpy(Buffer, &IoaVoltageOffset, sizeof(IoaVoltageOffset));
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//------------------------------- IOD Voltage Offset -------------------------------
+ Len = sizeof(IodVoltageOffset);
+ Buffer = MallocZ(Len);
+
+ MemCpy(Buffer, &IodVoltageOffset, sizeof(IodVoltageOffset));
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//------------------------------- Runtime Turbo -------------------------------
+ if (TdcTdpHobFound) {
+
+ Len = sizeof(CpuRuntimeTurbo);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ OneCoreRatioLimit = (UINT16)(TdcTdpHob->OneCoreRatioLimit);
+ MaxNonTurboRatio = ((UINT16)ReadMsr(0xCE) >> 8) & 0xFF;
+
+ if(OcDataHobFound) {
+ if(PerfTuneDataHob->PerfTuneDataHob.RuntimeTurboEanble == 0x1) {
+ if(PerfTuneDataHob->PerfTuneDataHob.RuntimeTurbo == 0xFFFF)
+ WRITE_MEM8_MCH(0x5990, (UINT8)OneCoreRatioLimit);
+ else
+ WRITE_MEM8_MCH(0x5990, (UINT8)PerfTuneDataHob->PerfTuneDataHob.RuntimeTurbo);
+ } else {
+ WRITE_MEM8_MCH(0x5990, 0xFF);
+ }
+ }
+
+ CpuRuntimeTurbo.DefaultDataValue = OneCoreRatioLimit;
+
+ if (NumOcBins == 7) {
+ CpuRuntimeTurbo.MaxDataValue = 0x3b; //max ratio is 59.
+ CpuRuntimeTurbo.MaxDisplayValue = 0x3b;
+ } else if((NumOcBins > 0) && (NumOcBins < 7)) {
+ CpuRuntimeTurbo.MaxDataValue = OneCoreRatioLimit + NumOcBins;
+ CpuRuntimeTurbo.MaxDisplayValue = OneCoreRatioLimit + NumOcBins;
+ }
+
+ CpuRuntimeTurbo.MinDataValue = MaxNonTurboRatio;
+ CpuRuntimeTurbo.MinDisplayValue = MaxNonTurboRatio;
+ CpuRuntimeTurbo.NumberOfValues = CpuRuntimeTurbo.MaxDataValue - CpuRuntimeTurbo.MinDataValue + 1;
+
+ MemCpy(Buffer, &CpuRuntimeTurbo, sizeof(CpuRuntimeTurbo));
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+ }
+//-------------------------- Mem Freq Setting ----------------------------------------
+ Len = sizeof(DramMultiGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ MemFreq = gMemInfoHobProtocol.MemInfoData.ddrFreq;
+ MemRatio = (NbFrequencyToRatio(MemFreq, gMemInfoHobProtocol.MemInfoData.RefClk, gBClkFrequency)*2);
+ DramMultiGaciData.DefaultDataValue = (UINT32)MemRatio;
+
+ MemCpy(Buffer, &DramMultiGaciData, sizeof(DramMultiGaciData));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, MemRatio);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//----------------------------Memory Clock Multiplier-----------------------
+ Len = sizeof(MemClockMultiplier);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ if(gMemInfoHobProtocol.MemInfoData.RefClk == MRC_REF_CLOCK_100){
+ RefClkRatio = 100;
+ }else{
+ RefClkRatio = 133;
+ }
+
+ MemClockMultiplier.DefaultDataValue = (UINT32)RefClkRatio;
+ MemCpy(Buffer, &MemClockMultiplier, sizeof(MemClockMultiplier));
+ Status = gPerfTuneAslProtocol->SyncHwValue(Buffer, RefClkRatio);
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//-------------------------- XMP Profile Selection -------------------------
+
+ Len = sizeof(XmpProfSelData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ //Add core to Update the Minimum and Maximum.
+ //According to XMP profile count.
+
+ // Default
+ XmpProfSelData.MaxDataValue = 1;
+ XmpProfSelData.MaxDisplayValue = 1;
+ XmpProfSelData.NumberOfValues = 2;
+
+ DDRFrequency[0] = NbGetDimmFrequency(NBMrcTimingData[2].tCK);
+ DDRFrequency[1] = NbGetDimmFrequency(NBMrcTimingData[3].tCK);
+
+ if (DDRFrequency[0] != fNoInit && DDRFrequency[1] == fNoInit) { // Porfile 1
+ XmpProfSelData.MaxDataValue = 2;
+ XmpProfSelData.MaxDisplayValue = 2;
+ XmpProfSelData.NumberOfValues = 3;
+ } else if (DDRFrequency[0] != fNoInit && DDRFrequency[1] != fNoInit) { // Both Profile
+ XmpProfSelData.MaxDataValue = 3;
+ XmpProfSelData.MaxDisplayValue = 3;
+ XmpProfSelData.NumberOfValues = 4;
+ }
+
+ MemCpy(Buffer, &XmpProfSelData, Len);
+
+ Status = gPerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+//---------------------------- GXDV START -----------------------------------
+
+ Len = sizeof(GXDV_DATA);
+ Len = (UINTN)Mul64(Len, 30); // 32 mean, define GXDV count.
+ Buffer = MallocZ(Len);
+ if(!Buffer) goto Done;
+
+ //Add code to change profile 1 display value
+ if (DDRFrequency[0] != fNoInit) {
+ MemRatio = NbFrequencyToRatio(DDRFrequency[0], gMemInfoHobProtocol.MemInfoData.RefClk, gBClkFrequency);
+
+ Pro1tCLGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tCL;
+ Pro1tRASGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRAS;
+ Pro1tRPGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRP;
+ Pro1tRCDGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRCD;
+ Pro1tWRGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tWR;
+ Pro1tRFCGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRFC;
+ Pro1tRRDGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRRD;
+ Pro1tWTRGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tWTR;
+ Pro1tRTPGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRTP;
+ Pro1tFAWGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tFAW;
+ Pro1tRCGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRC;
+ Pro1tREFIGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tREFI;
+ Pro1tCWLGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tCWL;
+// Pro1tRPabGxdvData.DisplayValue = (UINT32)NBMrcTimingData[2].tRPab;
+ Pro1DdrMulGxdvData.DisplayValue = (UINT32)DDRFrequency[0];
+ Pro1DdrMulGxdvData.DisplayValue = (UINT32)MemRatio * 2;
+ Pro1DdrClkMulGxdvData.DisplayValue = (UINT32)RefClkRatio;
+
+ }
+
+ //Add code to change Profile 2 display value
+ if (DDRFrequency[1] != fNoInit) {
+ MemRatio = NbFrequencyToRatio(DDRFrequency[1], gMemInfoHobProtocol.MemInfoData.RefClk, gBClkFrequency);
+
+ Pro2tCLGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tCL;
+ Pro2tRASGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRAS;
+ Pro2tRPGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRP;
+ Pro2tRCDGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRCD;
+ Pro2tWRGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tWR;
+ Pro2tRFCGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRFC;
+ Pro2tRRDGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRRD;
+ Pro2tWTRGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tWTR;
+ Pro2tRTPGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRTP;
+ Pro2tFAWGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tFAW;
+ Pro2tRCGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRC;
+ Pro2tREFIGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tREFI;
+ Pro2tCWLGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tCWL;
+// Pro1tRPabGxdvData.DisplayValue = (UINT32)NBMrcTimingData[3].tRPab;
+ Pro2DdrMulGxdvData.DisplayValue = (UINT32)DDRFrequency[1];
+ Pro2DdrMulGxdvData.DisplayValue = (UINT32)MemRatio * 2;
+ Pro2DdrClkMulGxdvData.DisplayValue = (UINT32)RefClkRatio;
+ }
+
+ MemCpy(Buffer, &Pro1tCLGxdvData, Len);
+
+ if (DDRFrequency[0] == fNoInit && DDRFrequency[1] == fNoInit) // Default
+ Status = gPerfTuneAslProtocol->SetGxdvData(XmpNotSupport,Buffer, Len);
+ else if (DDRFrequency[0] != fNoInit && DDRFrequency[1] == fNoInit) // Profile 1
+ Status = gPerfTuneAslProtocol->SetGxdvData(Profiles1,Buffer, Len);
+ else if (DDRFrequency[0] != fNoInit && DDRFrequency[1] != fNoInit) // Both Profile
+ Status = gPerfTuneAslProtocol->SetGxdvData(Both,Buffer, Len);
+
+ pBS->FreePool(Buffer);
+
+//---------------------------- GXDV END -----------------------------------
+
+Done:
+ // Kill event
+ pBS->CloseEvent(Event);
+}
+#endif
+#endif
+
+
+EFI_STATUS ReadSpdData (
+ IN EFI_SMBUS_HC_PROTOCOL *Smbus,
+ IN UINT8 SpdSalveAddr,
+ IN UINT8 Offset,
+ IN UINTN Count,
+ OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN Length;
+ EFI_SMBUS_OPERATION Operation;
+ EFI_SMBUS_DEVICE_COMMAND Command;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+
+ SlaveAddress.SmbusDeviceAddress = SpdSalveAddr >> 1;
+
+
+ for (Index = 0; Index < Count; Index++)
+ {
+ Command = Offset + Index;
+
+ Length = 1;
+ Operation = EfiSmbusReadByte;
+ Status = Smbus->Execute (Smbus,
+ SlaveAddress,
+ Command,
+ Operation,
+ FALSE,
+ &Length,
+ &Buffer[Index] );
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+#define MRC_FREQUENCY_MTB_OFFSET 1000000
+#define MRC_FREQUENCY_FTB_OFFSET 1000
+#define MRC_DDR3_800_TCK_MIN 2500000 /// 1/(800/2) femtoseconds
+#define MRC_DDR3_1000_TCK_MIN 2000000 /// 1/(1000/2) femtoseconds
+#define MRC_DDR3_1067_TCK_MIN 1875000 /// 1/(1067/2) femtoseconds
+#define MRC_DDR3_1200_TCK_MIN 1666666 /// 1/(1200/2) femtoseconds
+#define MRC_DDR3_1333_TCK_MIN 1500000 /// 1/(1333/2) femtoseconds
+#define MRC_DDR3_1400_TCK_MIN 1428571 /// 1/(1400/2) femtoseconds
+#define MRC_DDR3_1600_TCK_MIN 1250000 /// 1/(1600/2) femtoseconds
+#define MRC_DDR3_1800_TCK_MIN 1111111 /// 1/(1800/2) femtoseconds
+#define MRC_DDR3_1867_TCK_MIN 1071428 /// 1/(1867/2) femtoseconds
+#define MRC_DDR3_2000_TCK_MIN 1000000 /// 1/(2000/2) femtoseconds
+#define MRC_DDR3_2133_TCK_MIN 937500 /// 1/(2133/2) femtoseconds
+#define MRC_DDR3_2200_TCK_MIN 909090 /// 1/(2200/2) femtoseconds
+#define MRC_DDR3_2400_TCK_MIN 833333 /// 1/(2400/2) femtoseconds
+#define MRC_DDR3_2600_TCK_MIN 769230 /// 1/(2600/2) femtoseconds
+#define MRC_DDR3_2667_TCK_MIN 750000 /// 1/(2667/2) femtoseconds
+#define MRC_DDR3_2800_TCK_MIN 714285 /// 1/(2800/2) femtoseconds
+#define TREFIMULTIPLIER 1000 /// tREFI value defined in XMP 1.3 spec is actually in thousands of MTB units.
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+const NbTRangeTable NbRange[] = {
+ { 0xFFFFFFFF, fUnSupport, (0 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_800_TCK_MIN, f800, (1 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1000_TCK_MIN, f1000, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1067_TCK_MIN, f1067, (1 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1200_TCK_MIN, f1200, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1333_TCK_MIN, f1333, (1 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1400_TCK_MIN, f1400, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1600_TCK_MIN, f1600, (1 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1800_TCK_MIN, f1800, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_1867_TCK_MIN, f1867, (1 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2000_TCK_MIN, f2000, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2133_TCK_MIN, f2133, (1 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2200_TCK_MIN, f2200, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2400_TCK_MIN, f2400, (1 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2600_TCK_MIN, f2600, (0 << MRC_REF_CLOCK_133) | (1 << MRC_REF_CLOCK_100) },
+ { MRC_DDR3_2667_TCK_MIN, f2667, (1 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) },
+ { 0, fNoInit, (0 << MRC_REF_CLOCK_133) | (0 << MRC_REF_CLOCK_100) }
+};
+
+static BOOLEAN
+NbGetDimmTimeBase (
+ IN SPD_EXTREME_MEMORY_PROFILE *const XmpSpd,
+ IN UINT8 MemoryProfile,
+ OUT INT32 *const Mtb,
+ OUT INT32 *const Ftb
+ )
+{
+ UINT8 SpdMtbDividend;
+ UINT8 SpdMtbDivisor;
+ UINT8 SpdFtbDividend;
+ UINT8 SpdFtbDivisor;
+
+
+ SpdFtbDividend = XmpSpd->Header.FineTimeBase.Bits.Dividend;
+ SpdFtbDivisor = XmpSpd->Header.FineTimeBase.Bits.Divisor;
+ SpdMtbDividend = XmpSpd->Header.MediumTimeBase[MemoryProfile].Dividend.Bits.Dividend;
+ SpdMtbDivisor = XmpSpd->Header.MediumTimeBase[MemoryProfile].Divisor.Bits.Divisor;
+
+ *Ftb = (SpdFtbDivisor == 0) ? 0 : (SpdFtbDividend * MRC_FREQUENCY_FTB_OFFSET) / SpdFtbDivisor;
+ *Mtb = (SpdMtbDivisor == 0) ? 0 : (SpdMtbDividend * MRC_FREQUENCY_MTB_OFFSET) / SpdMtbDivisor;
+
+ return (*Mtb == 0) ? FALSE : TRUE;
+}
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+
+static
+MrcFrequency
+NbGetDimmFrequency (
+ IN UINT32 tCK
+ )
+{
+ UINT32 Index;
+ MrcFrequency XmpFrequency = fNoInit;
+ UINT32 NbRangeSize = (sizeof (NbRange) / sizeof (NbTRangeTable)) - 1;
+
+ if(tCK == 0 || tCK == 0xffffffff) return fNoInit;
+
+ for (Index = 0; Index < NbRangeSize; Index++) {
+ if ((tCK <= NbRange[Index].tCK) && (tCK > NbRange[Index + 1].tCK)) {
+ XmpFrequency = NbRange[Index].DDRFreq;
+ break;
+ }
+ }
+
+ while (Index) {
+ if ((NbRange[Index].RefClkFlag & (1 << gMemInfoHobProtocol.MemInfoData.RefClk)) == MRC_REF_CLOCK_133) {
+ XmpFrequency = NbRange[--Index].DDRFreq;
+ } else break;
+ }
+
+ return XmpFrequency;
+}
+/*
+static
+BOOLEAN
+NbGetDimmFrequency (
+ IN SPD_EXTREME_MEMORY_PROFILE *const XmpSpd,
+ IN UINT8 MemoryProfile,
+ IN UINT8 DimmCount
+ )
+{
+ INT32 MediumTimebase;
+ INT32 FineTimebase;
+ INT32 tCKminMtb;
+ INT32 tCKminFine;
+ INT32 tCKmin;
+ UINT32 NbRangeSize = (sizeof (NbRange) / sizeof (NbTRangeTable)) - 1;
+ UINT32 Index;
+ UINT32 TimingMTB;
+ INT32 TimingFTB;
+ SPD_EXTREME_MEMORY_PROFILE_DATA *ExtremeData;
+ NbXmpProfileData *ProfileTimingData;
+ MrcFrequency XmpFrequency;
+ UINT32 Calculated;
+ UINT32 tAAmin;
+ UINT32 tAAminFine;
+
+ XmpFrequency = fNoInit;
+ tCKmin = 0;
+ tCKminMtb = 0;
+ tCKminFine = 0;
+ TimingMTB = 0;
+ TimingFTB = 0;
+ Calculated = 0;
+ tAAmin = 0;
+ tAAminFine = 0;
+
+ ProfileTimingData = &XmpDimm[DimmCount].XmpProfileTiming[MemoryProfile];
+
+ if(NbGetDimmTimeBase (XmpSpd, MemoryProfile, &MediumTimebase, &FineTimebase)) {
+ ExtremeData = &XmpSpd->Data[MemoryProfile];
+ tCKminMtb = ExtremeData->tCKmin.Bits.tCKmin;
+ tCKminFine = ExtremeData->tCKminFine.Bits.tCKminFine;
+ tCKmin = (MediumTimebase * tCKminMtb) + (FineTimebase * tCKminFine);
+
+ for (Index = 0; Index < NbRangeSize; Index++) {
+ if ((tCKmin <= NbRange[Index].tCK) && (tCKmin > NbRange[Index + 1].tCK)) {
+ XmpFrequency = NbRange[Index].DDRFreq;
+ ProfileTimingData->TimingData.tCK = NbRange[Index].tCK;
+ break;
+ }
+ }
+
+ while (Index) {
+ if ((NbRange[Index].RefClkFlag & (1 << gMemInfoHobProtocol.MemInfoData.RefClk)) == MRC_REF_CLOCK_133) {
+ XmpFrequency = NbRange[--Index].DDRFreq;
+ } else break;
+ }
+// *tCKminIndex = Index;
+
+ // tCL
+ tAAmin = ExtremeData->tAAmin.Bits.tAAmin;
+ tAAminFine = ExtremeData->tAAminFine.Bits.tAAminFine;
+ tAAmin = (MediumTimebase * tAAmin) + (FineTimebase * tAAminFine);
+ ProfileTimingData->TimingData.tCL = (UINT16) ((tAAmin + (ProfileTimingData->TimingData.tCK - 1)) / ProfileTimingData->TimingData.tCK);
+ ProfileTimingData->TimingData.tCL = MIN (ProfileTimingData->TimingData.tCL, tCL_MAXIMUM);
+ // tCWL
+ TimingMTB = ExtremeData->tCWLmin.Bits.tCWLmin;
+ ProfileTimingData->TimingData.tCWL = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tCWL = MIN (ProfileTimingData->TimingData.tCWL, tCWL_MAXIMUM);
+ // tWR
+ TimingMTB = ExtremeData->tWRmin.Bits.tWRmin;
+ Calculated = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ //
+ // Special case, tWRmin values of 9, 11, 13, and 15 are not supported by DDR3 Mode Register 0 (MR0).
+ // If we see one of these values, then add one clock to it in order to make it valid.
+ //
+ if ((9 == Calculated) || (11 == Calculated) || (13 == Calculated) || (15 == Calculated)) {
+ Calculated++;
+ }
+ ProfileTimingData->TimingData.tWR = Calculated;
+ ProfileTimingData->TimingData.tWR = MIN (ProfileTimingData->TimingData.tWR, tWR_MAXIMUM);
+ // tRRD
+ TimingMTB = ExtremeData->tRRDmin.Bits.tRRDmin;
+ ProfileTimingData->TimingData.tRRD = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRRD = MIN (ProfileTimingData->TimingData.tRRD, tRRD_MAXIMUM);
+ // tRCD
+ TimingMTB = ExtremeData->tRCDmin.Bits.tRCDmin;
+ TimingFTB = ExtremeData->tRCDminFine.Bits.tRCDminFine;
+ ProfileTimingData->TimingData.tRCD = ((MediumTimebase * TimingMTB) + (FineTimebase * TimingFTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRCD = MIN (ProfileTimingData->TimingData.tRCD, tRCD_MAXIMUM);
+ // tRP
+ TimingMTB = ExtremeData->tRPmin.Bits.tRPmin;
+ TimingFTB = ExtremeData->tRPminFine.Bits.tRPminFine;
+ ProfileTimingData->TimingData.tRP = ((MediumTimebase * TimingMTB) + (FineTimebase * TimingFTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRP = MIN (ProfileTimingData->TimingData.tRP, tRP_MAXIMUM);
+ // tRAS
+ TimingMTB = ((UINT32) (ExtremeData->tRASMintRCMinUpper.Bits.tRASminUpper) << 8) | (UINT32) (ExtremeData->tRASmin.Bits.tRASmin);
+ ProfileTimingData->TimingData.tRAS = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRAS = MIN (ProfileTimingData->TimingData.tRAS, tRAS_MAXIMUM);
+ // tRFC
+ TimingMTB = ExtremeData->tRFCmin.Bits.tRFCmin;
+ ProfileTimingData->TimingData.tRFC = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRFC = MIN (ProfileTimingData->TimingData.tRFC, tRFC_MAXIMUM);
+
+ // tWTR
+ TimingMTB = ExtremeData->tWTRmin.Bits.tWTRmin;
+ ProfileTimingData->TimingData.tWTR = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tWTR = MIN (ProfileTimingData->TimingData.tWTR, tWTR_MAXIMUM);
+
+ // tRTP
+ TimingMTB = ExtremeData->tRTPmin.Bits.tRTPmin;
+ ProfileTimingData->TimingData.tRTP = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRTP = MIN (ProfileTimingData->TimingData.tRTP, tRTP_MAXIMUM);
+
+ // tFAW
+ TimingMTB = ((UINT32) (ExtremeData->tFAWMinUpper.Bits.tFAWminUpper) << 8) | (UINT32) (ExtremeData->tFAWmin.Bits.tFAWmin);
+ ProfileTimingData->TimingData.tFAW = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tFAW = MIN (ProfileTimingData->TimingData.tFAW, tFAW_MAXIMUM);
+
+ // tRC
+ TimingMTB = ((UINT32) (ExtremeData->tRASMintRCMinUpper.Bits.tRCminUpper) << 8) | (UINT32) (ExtremeData->tRCmin.Bits.tRCmin);
+ TimingFTB = ExtremeData->tRCminFine.Bits.tRCminFine;
+ ProfileTimingData->TimingData.tRC = ((MediumTimebase * TimingMTB) + (FineTimebase * TimingFTB) + (tCKmin - 1)) / tCKmin;
+ ProfileTimingData->TimingData.tRC = MIN (ProfileTimingData->TimingData.tRC, tRC_MAXIMUM);
+
+ // tREFI
+ TimingMTB = ExtremeData->tREFImin.Bits.tREFImin;
+ ProfileTimingData->TimingData.tREFI = (UINT32)Div64 (((Mul64 (MediumTimebase, TimingMTB * TREFIMULTIPLIER) + (tCKmin - 1))), tCKmin, NULL);
+ ProfileTimingData->TimingData.tREFI = MIN (ProfileTimingData->TimingData.tREFI, tREFI_MAXIMUM);
+ //NMode
+ TimingMTB = ExtremeData->SystemCmdRate.Bits.NMode;
+ if (TimingMTB > 0) {
+ ProfileTimingData->TimingData.NMode = ((MediumTimebase * TimingMTB) + (tCKmin - 1)) / tCKmin;
+ }
+ }
+
+ ProfileTimingData->DDRFreq = XmpFrequency;
+
+ if (XmpFrequency != fNoInit) return TRUE;
+
+ return FALSE;
+}
+*/
+#endif
+#endif
+
+EFI_STATUS NbReportXmpInfo(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+/*
+ EFI_STATUS Status;
+ EFI_SMBUS_HC_PROTOCOL *Smbus;
+ SPD_EXTREME_MEMORY_PROFILE XmpSpd;
+ VOID *SpdData = &XmpSpd;
+ UINT8 i, DimmCount;
+
+ Status = pBS->LocateProtocol( &gEfiSmbusProtocolGuid, \
+ NULL, \
+ &Smbus );
+ if (EFI_ERROR(Status))return Status;
+
+
+ for (i = DIMM1_SMBUS_ADDRESS, DimmCount = 0; DimmCount < 4; i += 2, DimmCount++) {
+ Status = ReadSpdData(Smbus, i, 176, 2, (UINT8*)SpdData);
+ if (EFI_ERROR(Status) || (XmpSpd.Header.XmpId != 0x4A0C)) continue;
+ Status = ReadSpdData(Smbus, i, 176, 79, (UINT8*)SpdData);
+ if (EFI_ERROR(Status)) continue;
+
+ if(XmpSpd.Header.XmpOrgConf.Bits.ProfileEnable1) {
+ NBPlatformData.XmpProfile1 = 1;
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+ NbGetDimmFrequency (SpdData, 0, DimmCount);
+#endif
+#endif
+ } else continue;
+
+ if(XmpSpd.Header.XmpOrgConf.Bits.ProfileEnable2) {
+ NBPlatformData.XmpProfile2 = 1;
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+ NbGetDimmFrequency (SpdData, 1, DimmCount);
+#endif
+#endif
+ }
+ }
+
+#if defined PERF_TUNE_SUPPORT && PERF_TUNE_SUPPORT == 1
+#if defined IXTU_LABLE_VERSION && IXTU_LABLE_VERSION >= 0x00C
+ // Channel 0 XmpProfile 1~2
+ XmpChannel[0].XmpProfileTiming[0].DDRFreq = MAX(XmpDimm[0].XmpProfileTiming[0].DDRFreq, XmpDimm[1].XmpProfileTiming[0].DDRFreq);
+ XmpChannel[0].XmpProfileTiming[1].DDRFreq = MAX(XmpDimm[0].XmpProfileTiming[1].DDRFreq, XmpDimm[1].XmpProfileTiming[1].DDRFreq);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tCL = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tCL, XmpDimm[1].XmpProfileTiming[0].TimingData.tCL);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tCL = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tCL, XmpDimm[1].XmpProfileTiming[1].TimingData.tCL);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tCWL = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tCWL, XmpDimm[1].XmpProfileTiming[0].TimingData.tCWL);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tCWL = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tCWL, XmpDimm[1].XmpProfileTiming[1].TimingData.tCWL);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tWR = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tWR, XmpDimm[1].XmpProfileTiming[0].TimingData.tWR);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tWR = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tWR, XmpDimm[1].XmpProfileTiming[1].TimingData.tWR);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRRD = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRRD, XmpDimm[1].XmpProfileTiming[0].TimingData.tRRD);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRRD = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRRD, XmpDimm[1].XmpProfileTiming[1].TimingData.tRRD);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRCD = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRCD, XmpDimm[1].XmpProfileTiming[0].TimingData.tRCD);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRCD = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRCD, XmpDimm[1].XmpProfileTiming[1].TimingData.tRCD);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRP = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRP, XmpDimm[1].XmpProfileTiming[0].TimingData.tRP);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRP = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRP, XmpDimm[1].XmpProfileTiming[1].TimingData.tRP);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRAS = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRAS, XmpDimm[1].XmpProfileTiming[0].TimingData.tRAS);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRAS = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRAS, XmpDimm[1].XmpProfileTiming[1].TimingData.tRAS);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRFC = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRFC, XmpDimm[1].XmpProfileTiming[0].TimingData.tRFC);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRFC = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRFC, XmpDimm[1].XmpProfileTiming[1].TimingData.tRFC);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tWTR = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tWTR, XmpDimm[1].XmpProfileTiming[0].TimingData.tWTR);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tWTR = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tWTR, XmpDimm[1].XmpProfileTiming[1].TimingData.tWTR);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRTP = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRTP, XmpDimm[1].XmpProfileTiming[0].TimingData.tRTP);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRTP = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRTP, XmpDimm[1].XmpProfileTiming[1].TimingData.tRTP);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tFAW = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRC, XmpDimm[1].XmpProfileTiming[0].TimingData.tFAW);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tFAW = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRC, XmpDimm[1].XmpProfileTiming[1].TimingData.tFAW);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tREFI = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tREFI, XmpDimm[1].XmpProfileTiming[0].TimingData.tREFI);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tREFI = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tREFI, XmpDimm[1].XmpProfileTiming[1].TimingData.tREFI);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.tRC = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.tRC, XmpDimm[1].XmpProfileTiming[0].TimingData.tRC);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.tRC = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.tRC, XmpDimm[1].XmpProfileTiming[1].TimingData.tRC);
+ XmpChannel[0].XmpProfileTiming[0].TimingData.NMode = MAX(XmpDimm[0].XmpProfileTiming[0].TimingData.NMode, XmpDimm[1].XmpProfileTiming[0].TimingData.NMode);
+ XmpChannel[0].XmpProfileTiming[1].TimingData.NMode = MAX(XmpDimm[0].XmpProfileTiming[1].TimingData.NMode, XmpDimm[1].XmpProfileTiming[1].TimingData.NMode);
+
+ // Channel 1 XmpProfile 1~2
+ XmpChannel[1].XmpProfileTiming[0].DDRFreq = MAX(XmpDimm[2].XmpProfileTiming[0].DDRFreq, XmpDimm[3].XmpProfileTiming[0].DDRFreq);
+ XmpChannel[1].XmpProfileTiming[1].DDRFreq = MAX(XmpDimm[2].XmpProfileTiming[1].DDRFreq, XmpDimm[3].XmpProfileTiming[1].DDRFreq);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tCL = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tCL, XmpDimm[3].XmpProfileTiming[0].TimingData.tCL);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tCL = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tCL, XmpDimm[3].XmpProfileTiming[1].TimingData.tCL);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tCWL = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tCWL, XmpDimm[3].XmpProfileTiming[0].TimingData.tCWL);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tCWL = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tCWL, XmpDimm[3].XmpProfileTiming[1].TimingData.tCWL);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tWR = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tWR, XmpDimm[3].XmpProfileTiming[0].TimingData.tWR);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tWR = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tWR, XmpDimm[3].XmpProfileTiming[1].TimingData.tWR);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRRD = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRRD, XmpDimm[3].XmpProfileTiming[0].TimingData.tRRD);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRRD = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRRD, XmpDimm[3].XmpProfileTiming[1].TimingData.tRRD);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRCD = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRCD, XmpDimm[3].XmpProfileTiming[0].TimingData.tRCD);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRCD = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRCD, XmpDimm[3].XmpProfileTiming[1].TimingData.tRCD);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRP = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRP, XmpDimm[3].XmpProfileTiming[0].TimingData.tRP);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRP = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRP, XmpDimm[3].XmpProfileTiming[1].TimingData.tRP);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRAS = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRAS, XmpDimm[3].XmpProfileTiming[0].TimingData.tRAS);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRAS = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRAS, XmpDimm[3].XmpProfileTiming[1].TimingData.tRAS);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRFC = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRFC, XmpDimm[3].XmpProfileTiming[0].TimingData.tRFC);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRFC = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRFC, XmpDimm[3].XmpProfileTiming[1].TimingData.tRFC);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tWTR = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tWTR, XmpDimm[3].XmpProfileTiming[0].TimingData.tWTR);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tWTR = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tWTR, XmpDimm[3].XmpProfileTiming[1].TimingData.tWTR);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRTP = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRTP, XmpDimm[3].XmpProfileTiming[0].TimingData.tRTP);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRTP = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRTP, XmpDimm[3].XmpProfileTiming[1].TimingData.tRTP);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tFAW = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRC, XmpDimm[3].XmpProfileTiming[0].TimingData.tFAW);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tFAW = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRC, XmpDimm[3].XmpProfileTiming[1].TimingData.tFAW);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tREFI = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tREFI, XmpDimm[3].XmpProfileTiming[0].TimingData.tREFI);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tREFI = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tREFI, XmpDimm[3].XmpProfileTiming[1].TimingData.tREFI);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.tRC = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.tRC, XmpDimm[3].XmpProfileTiming[0].TimingData.tRC);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.tRC = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.tRC, XmpDimm[3].XmpProfileTiming[1].TimingData.tRC);
+ XmpChannel[1].XmpProfileTiming[0].TimingData.NMode = MAX(XmpDimm[2].XmpProfileTiming[0].TimingData.NMode, XmpDimm[3].XmpProfileTiming[0].TimingData.NMode);
+ XmpChannel[1].XmpProfileTiming[1].TimingData.NMode = MAX(XmpDimm[2].XmpProfileTiming[1].TimingData.NMode, XmpDimm[3].XmpProfileTiming[1].TimingData.NMode);
+
+ // Output XmpProfile 1~2
+ XmpProfileTiming[0].DDRFreq = MAX(XmpChannel[0].XmpProfileTiming[0].DDRFreq, XmpChannel[1].XmpProfileTiming[0].DDRFreq);
+ XmpProfileTiming[1].DDRFreq = MAX(XmpChannel[0].XmpProfileTiming[1].DDRFreq, XmpChannel[1].XmpProfileTiming[1].DDRFreq);
+ XmpProfileTiming[0].TimingData.tCL = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tCL, XmpChannel[1].XmpProfileTiming[0].TimingData.tCL);
+ XmpProfileTiming[1].TimingData.tCL = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tCL, XmpChannel[1].XmpProfileTiming[1].TimingData.tCL);
+ XmpProfileTiming[0].TimingData.tCWL = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tCWL, XmpChannel[1].XmpProfileTiming[0].TimingData.tCWL);
+ XmpProfileTiming[1].TimingData.tCWL = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tCWL, XmpChannel[1].XmpProfileTiming[1].TimingData.tCWL);
+ XmpProfileTiming[0].TimingData.tWR = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tWR, XmpChannel[1].XmpProfileTiming[0].TimingData.tWR);
+ XmpProfileTiming[1].TimingData.tWR = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tWR, XmpChannel[1].XmpProfileTiming[1].TimingData.tWR);
+ XmpProfileTiming[0].TimingData.tRRD = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRRD, XmpChannel[1].XmpProfileTiming[0].TimingData.tRRD);
+ XmpProfileTiming[1].TimingData.tRRD = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRRD, XmpChannel[1].XmpProfileTiming[1].TimingData.tRRD);
+ XmpProfileTiming[0].TimingData.tRCD = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRCD, XmpChannel[1].XmpProfileTiming[0].TimingData.tRCD);
+ XmpProfileTiming[1].TimingData.tRCD = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRCD, XmpChannel[1].XmpProfileTiming[1].TimingData.tRCD);
+ XmpProfileTiming[0].TimingData.tRP = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRP, XmpChannel[1].XmpProfileTiming[0].TimingData.tRP);
+ XmpProfileTiming[1].TimingData.tRP = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRP, XmpChannel[1].XmpProfileTiming[1].TimingData.tRP);
+ XmpProfileTiming[0].TimingData.tRAS = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRAS, XmpChannel[1].XmpProfileTiming[0].TimingData.tRAS);
+ XmpProfileTiming[1].TimingData.tRAS = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRAS, XmpChannel[1].XmpProfileTiming[1].TimingData.tRAS);
+ XmpProfileTiming[0].TimingData.tRFC = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRFC, XmpChannel[1].XmpProfileTiming[0].TimingData.tRFC);
+ XmpProfileTiming[1].TimingData.tRFC = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRFC, XmpChannel[1].XmpProfileTiming[1].TimingData.tRFC);
+ XmpProfileTiming[0].TimingData.tWTR = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tWTR, XmpChannel[1].XmpProfileTiming[0].TimingData.tWTR);
+ XmpProfileTiming[1].TimingData.tWTR = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tWTR, XmpChannel[1].XmpProfileTiming[1].TimingData.tWTR);
+ XmpProfileTiming[0].TimingData.tRTP = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRTP, XmpChannel[1].XmpProfileTiming[0].TimingData.tRTP);
+ XmpProfileTiming[1].TimingData.tRTP = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRTP, XmpChannel[1].XmpProfileTiming[1].TimingData.tRTP);
+ XmpProfileTiming[0].TimingData.tFAW = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tFAW, XmpChannel[1].XmpProfileTiming[0].TimingData.tFAW);
+ XmpProfileTiming[1].TimingData.tFAW = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tFAW, XmpChannel[1].XmpProfileTiming[1].TimingData.tFAW);
+ XmpProfileTiming[0].TimingData.tREFI = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tREFI, XmpChannel[1].XmpProfileTiming[0].TimingData.tREFI);
+ XmpProfileTiming[1].TimingData.tREFI = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tREFI, XmpChannel[1].XmpProfileTiming[1].TimingData.tREFI);
+ XmpProfileTiming[0].TimingData.tRC = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.tRC, XmpChannel[1].XmpProfileTiming[0].TimingData.tRC);
+ XmpProfileTiming[1].TimingData.tRC = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.tRC, XmpChannel[1].XmpProfileTiming[1].TimingData.tRC);
+ XmpProfileTiming[0].TimingData.NMode = MAX(XmpChannel[0].XmpProfileTiming[0].TimingData.NMode, XmpChannel[1].XmpProfileTiming[0].TimingData.NMode);
+ XmpProfileTiming[1].TimingData.NMode = MAX(XmpChannel[0].XmpProfileTiming[1].TimingData.NMode, XmpChannel[1].XmpProfileTiming[1].TimingData.NMode);
+#endif
+#endif
+
+ Status = pRS->SetVariable (
+ L"NBPlatformData",
+ &gSetupGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (NB_PLATFORM_DATA),
+ &NBPlatformData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Kill event
+ pBS->CloseEvent(Event);
+*/
+ return EFI_SUCCESS;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************