diff options
Diffstat (limited to 'Chipset/SB/SBPEI.c')
-rw-r--r-- | Chipset/SB/SBPEI.c | 3430 |
1 files changed, 3430 insertions, 0 deletions
diff --git a/Chipset/SB/SBPEI.c b/Chipset/SB/SBPEI.c new file mode 100644 index 0000000..918f226 --- /dev/null +++ b/Chipset/SB/SBPEI.c @@ -0,0 +1,3430 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBPEI.c 57 5/27/15 2:26a Dennisliu $ +// +// $Revision: 57 $ +// +// $Date: 5/27/15 2:26a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBPEI.c $ +// +// 57 5/27/15 2:26a Dennisliu +// [TAG] EIP219399 +// [Category] Improvement +// [Description] Static code analysis issue found in Aptio4 Intel +// LynxPoint PCH module +// [Files] Chipset\SB\SBPEI.c +// +// 56 11/17/14 7:24a Mirayang +// [TAG] EIP190402 +// [Category] New Feature +// [Description] Support BootScriptHide eModule on Sharkbay CRB project +// +// 55 9/23/14 6:12a Mirayang +// [TAG] EIP183246 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] BIOS capsule update usb issue +// [RootCause] Boot mode conditions miss "BOOT_ON_FLASH_UPDATE" in +// InitUsbMisc(). +// [Solution] Add "BOOT_ON_FLASH_UPDATE" this boot mode conditions . +// +// 54 7/21/14 10:42p Mirayang +// [TAG] EIP176923 +// [Category] Improvement +// [Description] Program BUC.SDO to 1 on normal boot in PCH component. +// +// 53 4/01/14 10:18p Barretlin +// [TAG] EIP156783 +// [Category] Improvement +// [Description] fix build error when removing usb recovery module +// [Files] SbPei.c +// +// 52 1/14/14 1:37a Barretlin +// [TAG] EIP150529 +// [Category] Improvement +// [Description] System hang due to dysfunctional MRC delay routine +// [Files] SBPei.c +// +// 51 1/08/14 11:18p Barretlin +// [TAG] EIP149596 +// [Category] Improvement +// [Description] system cannot enter to recovery mode when CMOS is bad +// [Files] SBPEI.c +// +// 50 10/29/13 12:38a Barretlin +// [TAG] EIP136997 +// [Category] Improvement +// [Description] fix build error when SUPPORT_RAID_DRIVER token is 0 +// [Files] SBPei.c +// +// 49 10/06/13 2:31a Barretlin +// [TAG] EIP138340 +// [Category] Improvement +// [Description] SATA drive detection issue in PCH Platform BIOS +// reference code revision 1.6.2 +// [Files] SB.sdl SBPEI.c +// +// 48 9/17/13 2:48p Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] use token to decide SATA RxEq policy vaule +// [Files] SB.sdl SBPei.c +// +// 47 9/17/13 8:43a Barretlin +// [TAG] EIP136354 +// [Category] Improvement +// [Description] remove setting RCBA Coprocessor Error Enable bit +// [Files] SB.sdl SbPei.c +// +// 46 8/23/13 4:34a Barretlin +// [TAG] EIP133819 +// [Category] Improvement +// [Description] change platform policy revision to 4 +// [Files] SBPEI.c +// +// 45 8/23/13 3:42a Barretlin +// [TAG] EIP133819 +// [Category] Improvement +// [Description] update for Intel PCH RC 1.6.2.0 +// [Files] SB.sdl SBPEI.c +// +// 44 7/17/13 8:01a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Let's GPIO GPINDIS bit setting by custom define except +// GPO. +// [Files] SBPEI.c +// +// 43 5/23/13 1:56a Scottyang +// [TAG] EIP120623 +// [Category] Improvement +// [Description] LCD turn on automatically when resume from S3. +// [Files] SBPEI.c, SBDxe.c, AcpiModeEnable.c +// +// 42 5/13/13 9:14a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Set time to default when clear cmos by jumper or +// remove battery. +// [Files] SBPEI.c +// +// 40 5/08/13 4:37a Scottyang +// [TAG] EIP123117 +// [Category] Improvement +// [Description] Fixed enable USB precondition, and do power off, power +// on, it will hang 9C. +// [Files] SBPEI.c +// +// 39 5/08/13 3:09a Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Enable bit set at wrong place. +// [RootCause] The offset error. +// [Solution] Make offset correct. +// [Files] SBPEI.c +// +// 37 5/03/13 1:42a Scottyang +// [TAG] EIP115528 +// [Category] Improvement +// [Description] Support XHCI port recovery when reset after boot to OS +// with XHCI driver. +// [Files] SBPEI.c +// +// 36 4/24/13 6:42a Scottyang +// [TAG] EIP114861 +// [Category] Improvement +// [Description] For PTT(Fast boot) 15 can reduce post for CD-ROM. +// [Files] SBPEI.c +// +// 35 4/24/13 4:20a Scottyang +// [TAG] EIP118667 +// [Category] Improvement +// [Description] For ULT when GPIO is GPO will also set GPI_DIS_DISABLE. +// [Files] SBPEI.c +// +// 34 4/24/13 2:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Porting GPI interrupt by LPT-LP EDS 1.5. +// [Files] SB.sdl, SB.H, SBPPI.h, SBPEI.c +// +// 33 4/23/13 4:51a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Add token "ONLY_CLEAR_RTC_EN_IN_PEI" for improve +// "EIP120623". +// [Files] AcpiModeEnable.c; SB.SDL; SBPEI.c +// +// 31 4/18/13 12:18a Wesleychen +// [TAG] EIP120623 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] LCD doesn't turn on automatically when resume from S3. +// [RootCause] PM1_STS (PMBASE+00h) are cleared in EnableAcpiMode(). +// [Solution] Avoid PM1_STS clearing behavior is occurring in S3 +// resuming. +// *AcpiModeEnable.c Rev#8~11(EIP101628 & EIP118531) are are +// no need be existence. +// [Files] SBPEI.c; AcpiModeEnable.c +// +// 29 3/15/13 3:33a Scottyang +// [TAG] EIP118121 +// [Category] Improvement +// [Description] Update PCH RC 1.3.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupData.h +// +// 28 3/12/13 7:40a Scottyang +// [TAG] EIP115528 +// [Category] Improvement +// [Description] USB ports are connected to EHCI not XHCI When recovery. +// [Files] SBPEI.c +// +// 27 2/26/13 1:02a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Follow intel BIOS V112 to change IRQ rout. +// [Files] SB.sdl, SBPEI.c +// +// 26 2/09/13 12:12a Scottyang +// [TAG] EIP114922 +// [Category] Improvement +// [Description] Update PCH RC 1.1.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupDara.h +// +// 25 1/31/13 10:51a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add delay for HDD recovery. +// [Files] SBPEI.c +// +// 24 1/30/13 1:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fix build error at 4653. +// [Files] SBPEI.c +// +// 23 1/27/13 11:01p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Capsule 2.0 crash dump link function. +// [Files] SBPEI.c +// SBDxe.c +// SBRun.c +// +// 22 1/11/13 1:51a Scottyang +// [TAG] EIP88358 +// [Category] Improvement +// [Description] Add FORCE_USER_TO_SETUP_IF_CMOS_BAD token +// [Files] SBDex.c, SBPei.c, RTC.h, SB.sdl +// +// 21 12/24/12 5:51a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add option for XHCI Idel L1 workaroung. +// [Files] GetSetupData.c, SbSetupData.h, SB.sd, SB.uni, SBDxe.c, +// SBPEI.c +// +// 20 12/18/12 6:10a Scottyang +// [TAG] EIP109697 +// [Category] Improvement +// [Description] Update PCH RC 0.8.1 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd, +// SbSetupData.c, GetSetupDate.c +// +// 19 12/13/12 10:31a Scottyang +// [TAG] EIP106687 +// [Category] Improvement +// [Description] Add option for delay to detect PCIE card. +// [Files] SBPEI.c, SB.sd, SB.uni, GetSetupData.c, SbSetupData.h, +// PciBus.c +// +// 18 12/13/12 10:17a Scottyang +// [TAG] EIP107424 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System stops at CKP 0x9C when system performs a cool boot +// and AMI debugger is enabled. +// [RootCause] Unexpected USB EHCI Legacy Support Extended status is +// rised, it is out of USB module control. +// [Solution] Clear unexpected USB EHCI Legacy Support Extended +// status. +// [Files] SBPEI.c +// +// 17 11/20/12 9:47a Scottyang +// [TAG] EIP107014 +// [Category] Improvement +// [Description] Update RC 0.8.0 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SbSetupData.c, GetSetupDate.c +// +// 16 11/06/12 8:12a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Reduce function "GetPchSeries()". +// [Files] SBPEI.c, SBDxe.c, SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 15 10/25/12 8:16a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add new device and remove device which no use +// [Files] SBPEI.c, SB.sdl +// +// 14 10/16/12 4:16a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Assign IRQ for device 21 +// +// 13 10/14/12 8:33a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] One rom for two chip and one chip. +// [Files] SPPEIBoard.c, SB.sd, SBDxe.c, SBPEI.c, PCH.asl +// +// 12 10/12/12 4:55a Scottyang +// [TAG] EIP87695 +// [Category] Improvement +// [Description] System should reboot successfully next time if S3 +// resume fail +// [Files] SB.sdl, SBPei.c +// +// 11 10/11/12 11:15p Scottyang +// [TAG] EIP86096 +// [Category] Improvement +// [Description] Fix SATA AHCI port4 & 5 can't loading recovery image. +// [Files] SBPei.c +// +// 10 9/26/12 3:55a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for Intel PCH LPT RC070. +// [Files] SB.sdl, SBDXE.c, SBPEI.c, Pch.sdl, SB.sd, SB.uni +// +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 9 9/12/12 5:20a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Force HPET enabled for MRC initialization. +// [Files] SB.sd, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Modify for ULT GPIO changed by PCH LPT-LP EDS 1.0. +// [Files] SB.H, SB.sdl, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBPEI.c +// +// 8 8/24/12 6:51a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Sync USB policy for UsbPrecondition function. +// [Files] SBPEI.c +// +// 7 8/14/12 11:26p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update "SB_TEMP_MMIO_BASE" and +// "EHCI_MMIO_BASE_ADDRESS". +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// 6 8/13/12 10:29a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update correct MMIO BASE for TempMemBaseAddr policy. +// [Files] SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update PCH Policy. +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement USB Precondition option for policy +// "UsbPrecondition". +// [Files] GetSetupData.c, SB.sd, SB.uni, SbSetupData.h, SBDxe.c, +// SBPEI.c +// +// 5 7/27/12 6:14a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update setup items and policies. +// [Files] GetSetupData.c, SB.sdl, SB.sd, SB.uni, SbSetupData.h, +// SBPEI.c, SBDXE.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 4 7/02/12 10:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Updated and modified for PCH RC 0.6.0. +// [Files] SBGeneric.c, SB.sdl, SBCspLib.h, SBDxe.c, SBPEI.c +// +// 3 6/13/12 11:34p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement Warm Boot function for Secure Flash feature. +// [Files] SB.H, SB.mak, SB.sdl, SBDxe.c, SBGeneric.c, SBPEI.c, +// SBSMI.c +// +// 2 2/24/12 2:35a Victortu +// Support RapidStart_SUPPORT. +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBPEI.C +// +// Description: This file contains code for South Bridge initialization +// in the PEI stage +// +//<AMI_FHDR_END> +//************************************************************************* + +//---------------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------------- + +#include <Efi.h> +#include <Pei.h> +#include <Token.h> +#include <AmiPeiLib.h> +#include <Hob.h> +#include <Setup.h> +#include <AmiCspLib.h> +// Produced/used PPI interfaces +#include <ppi\PciCfg2.h> +#include <ppi\SBPPI.h> +#include <ppi\CpuIo.h> +#include <ppi\CspLibPpi.h> +#include <RTC.h> +#include <PchAccess.h> +#include <Ppi\PchUsbPolicy\PchUsbPolicy.h> +#include <Ppi\PchInit\PchInit.h> + +#include <Ppi\SmbusPolicy\SmbusPolicy.h> +#include <Ppi\PchPlatformPolicy\PchPlatformPolicy.h> + +#if defined iME_SUPPORT && iME_SUPPORT +#include <Guid\MeBiosExtensionSetup\MeBiosExtensionSetup.h> +#endif + +#if SB_RESET_PPI_SUPPORT +#include <Ppi\Reset.h> +#endif + +#if ATAPI_RECOVERY_SUPPORT +#include <Ppi\AtaController.h> +#endif + +#if SB_STALL_PPI_SUPPORT +#include <Ppi\Stall.h> +#endif + +#if WdtPei_SUPPORT +#include "ppi\Wdt\Wdt.h" +#endif +#include <ppi\NBPPI.h> + +#if Capsule2_0_SUPPORT +#include <ppi\capsule.h> //CAPSULE20 +#endif + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) +#include <FastBoot.h> + +#define SATA1_BDF (0x1f << 3 | 0x02) +#define SATA2_BDF (0x1f << 3 | 0x05) +#endif +//---------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//---------------------------------------------------------------------------- +// Constant Definition(s) +#define EHCI_MEMORY_SPACE 0x400 +#define TIMER_RESOLUTION 1 +#define S3_SLP_TYP 0x05 + +#ifndef SMM_SUPPORT + #define SMM_SUPPORT 0 +#endif + +#define RETRAIN_DELAY 50 // [EIP106687] + +// Macro Definition(s) + +// Type Definition(s) +#if defined iME_SUPPORT && iME_SUPPORT +// TS on DIMM defines +#define TS_ON_CHANNEL0_SLOT_0_DIMM 0x1 +#define TS_ON_CHANNEL1_SLOT_0_DIMM 0x2 +#define TS_ON_C0_S0_AND_C1_S0_DIMM 0x3 +#endif + +#ifndef CAPSULE_SUPPORT + +#if defined Capsule2_0_SUPPORT && Capsule2_0_SUPPORT +#define CAPSULE_SUPPORT 1 +#else +#define CAPSULE_SUPPORT 0 +#endif + +#endif + +typedef struct _SATA_LENGTH_CONFIG { + UINT8 SataGen1RxEqEnable; + UINT8 SataGen1RxEqValue; + UINT8 SataGen2RxEqEnable; + UINT8 SataGen2RxEqValue; + UINT8 SataGen3RxEqEnable; + UINT8 SataGen3RxEqValue; +} SATA_LENGTH_CONFIG; +// Function Prototype(s) + +BOOLEAN IsRecovery ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +#if SB_RESET_PPI_SUPPORT +EFI_STATUS SBPEI_ResetSystem ( + IN EFI_PEI_SERVICES **PeiServices +); +#endif + +#if SB_STALL_PPI_SUPPORT +EFI_STATUS SBPEI_Stall ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_STALL_PPI *This, + IN UINTN Microseconds +); +#endif + +#if ATAPI_RECOVERY_SUPPORT +EFI_STATUS EFIAPI EnableAtaChannel ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ATA_CONTROLLER_PPI *This, + IN UINT8 ChannelIndex +); +#endif + +BOOLEAN IsS3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +VOID ProgramGPIO ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData, + IN AMI_GPIO_INIT_TABLE_STRUCT *pTable +); + +VOID ProgramSBSubId( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi +); + +VOID InitPCIe ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID InitSMBus ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID InitUsbMisc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_BOOT_MODE BootMode +); + +EFI_STATUS UpdateBootMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS ProgramSBRegAfterMemInstalled ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegBeforeEndofPei ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegAfterMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegEndOfMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +VOID InitPMRegs( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData +); + +VOID InitRTC( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +VOID WriteSBDefaultSubId ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID ProgramRCRBMmio ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +EFI_STATUS +ProgramSBIoDecodeRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +ProgramPchDeviceBase ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +GeneralPowerFailureHandler ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +SetTheStateToGoAfterG3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS InstallPchPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS +InstallAmtPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS +CreateAmtForcePushPetPolicyHob( + IN EFI_PEI_SERVICES **PeiServices +); + +//---------------------------------------------------------------------------- +// Variable and External Declaration(s) +//---------------------------------------------------------------------------- +// Variable Declaration(s) + +// GUID Definition(s) +EFI_GUID gAmiPEISBInitPolicyGuid = AMI_PEI_SBINIT_POLICY_PPI_GUID; +EFI_GUID gAmiPEIPCITableInitPpiGuid = AMI_PEI_PCI_TABLE_INIT_PPI_GUID; +EFI_GUID gMasterBootModeGuid = EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI; +EFI_GUID gRecoveryBootModeGuid = EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI; +EFI_GUID gEfiPeiPermMemInstalledGuid = EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI; +EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID; +EFI_GUID gPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID; +EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID; +EFI_GUID gSetupGuid = SETUP_GUID; +EFI_GUID gPchUsbPolicyPpiGuid = PCH_USB_POLICY_PPI_GUID; +EFI_GUID gPchInitPpiGuid = PCH_INIT_PPI_GUID; + +EFI_GUID gPeiCompleteMRCGuid = AMI_PEI_AFTER_MRC_GUID; + +#if SB_STALL_PPI_SUPPORT +EFI_GUID gStallPpiGuid = EFI_PEI_STALL_PPI_GUID; +#endif + +#if SB_RESET_PPI_SUPPORT +EFI_GUID gPeiResetPpiGuid = EFI_PEI_RESET_PPI_GUID; +#endif + +#if ATAPI_RECOVERY_SUPPORT +EFI_GUID gPeiAtaControllerPpiGuid = PEI_ATA_CONTROLLER_PPI_GUID; +#endif + +#if WdtPei_SUPPORT +EFI_GUID gWdtPpiGuid = WDT_PPI_GUID; +#endif + +EFI_GUID gOemPchPlatformPolicyOverridePpiGuid = AMI_PEI_SB_OEM_PLATFORM_POLICY_OVERRIDE_PPI_GUID; + +// PPI Definition(s) + +static AMI_PEI_SBINIT_POLICY_PPI mAMIPEISBInitPolicyPpi = { + TRUE +}; + +#if ATAPI_RECOVERY_SUPPORT +static PEI_ATA_CONTROLLER_PPI mAtaControllerPpi = { + EnableAtaChannel +}; +#endif + +#if SB_STALL_PPI_SUPPORT +static EFI_PEI_STALL_PPI mStallPpi = { + TIMER_RESOLUTION, + SBPEI_Stall +}; +#endif + +#if SB_RESET_PPI_SUPPORT +static EFI_PEI_RESET_PPI mResetPpi = { + SBPEI_ResetSystem +}; +#endif + +// PPI that are installed + +#if SB_STALL_PPI_SUPPORT +static EFI_PEI_PPI_DESCRIPTOR mBeforeBootModePpiList[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gStallPpiGuid, &mStallPpi }, +}; +#endif + +static EFI_PEI_PPI_DESCRIPTOR mBootModePpi[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gMasterBootModeGuid, NULL }, +}; + +static EFI_PEI_PPI_DESCRIPTOR mRecoveryModePpi[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gRecoveryBootModeGuid, NULL }, +}; + +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { +#if ATAPI_RECOVERY_SUPPORT + { EFI_PEI_PPI_DESCRIPTOR_PPI, \ + &gPeiAtaControllerPpiGuid, &mAtaControllerPpi }, +#endif +#if SB_RESET_PPI_SUPPORT + { EFI_PEI_PPI_DESCRIPTOR_PPI, &gPeiResetPpiGuid, &mResetPpi }, +#endif + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPEISBInitPolicyGuid, &mAMIPEISBInitPolicyPpi } +}; + +// PPI that are notified + +static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gEfiPeiEndOfPeiPhasePpiGuid, ProgramSBRegBeforeEndofPei }, +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR mMemoryReadyNotify[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiPermMemInstalledGuid, ProgramSBRegAfterMemInstalled } +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR AfterMrcNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPeiAfterMrcGuid, ProgramSBRegAfterMrc }, +}; +static EFI_PEI_NOTIFY_DESCRIPTOR EndOfMrcNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPeiEndOfMemDetectGuid, ProgramSBRegEndOfMrc }, +}; + +static EFI_PEI_PPI_DESCRIPTOR StallPpiDescriptor_InMemory[] = +{ + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gStallPpiGuid, + &mStallPpi + } +}; + +// External Declaration(s) + +extern AMI_GPIO_INIT_TABLE_STRUCT stSB_GPIODefaultInitTable[]; +extern AMI_GPIO_INIT_TABLE_STRUCT stSB_GPIODefaultULTInitTable[]; + +extern EFI_STATUS CountTime ( + IN UINTN DelayTime, + IN UINT16 BaseAddr +); + +#if SB_RESET_PPI_SUPPORT +extern VOID SBLib_ResetSystem ( + IN EFI_RESET_TYPE ResetType +); +#endif + +// Function Definition(s) + +#ifdef RAPID_START_FLAG + +#define RAPID_START_FLAG_ENTRY_DONE BIT0 + +EFI_STATUS +RapidStartGetFlag ( + OUT UINT8 *Value + ) +{ + *Value = RtcRead (FFS_NV_FLAG_REG); + return EFI_SUCCESS; +} + +BOOLEAN +RapidStartResumeCheck ( + VOID +) +{ + EFI_STATUS Status; + BOOLEAN RapidStartFlag; + + Status = RapidStartGetFlag (&RapidStartFlag); + if ( !EFI_ERROR (Status) && ((RapidStartFlag & RAPID_START_FLAG_ENTRY_DONE) != 0)) { + return TRUE; + } + + return FALSE; +} +#endif + +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsS3 +// +// Description: This function determines if the system is resuming from an S3 +// sleep state. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - It is an S3 Resume +// FALSE - It is not an S3 Resume +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsS3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + // Check PWR_FLR Bit + if ((READ_PCI8_SB(R_PCH_LPC_GEN_PMCON_3) & B_PCH_LPC_GEN_PMCON_PWR_FLR) == 0) // 0xA4 + // Check PWRBTN override + if ((READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_PRBTNOR) == 0) // 0x00 + // Check WAK_STS bit + if ((READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_WAK)) // 0x00 + // Check the sleep type + if ((READ_IO16_PM(R_PCH_ACPI_PM1_CNT) & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) //0x04 + return TRUE; + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsS4 +// +// Description: This function determines if the system is resuming from an S4 +// sleep state. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - It is an S4 Resume +// FALSE - It is not an S4 Resume +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsS4 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + if ((READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0x1c00) == 0x1800) //0x04 + return TRUE; + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsCmosBad +// +// Description: This function determines CMOS data is available. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - CMOS data is bad +// FALSE - CMOS DATA is available +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsCmosBad ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + return (READ_IO8_RTC(CMOS_BAD_REG | RTC_NMI_MASK) & 0xc0) ? TRUE : FALSE; +} + +#if KBC_SUPPORT && Recovery_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ResetKbc +// +// Description: This function resets Keyboard controller for Ctrl-Home +// recovery function. +// +// Input: PeiServices - Pointer to the Pei Services function and +// data structure +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +// +// Notes: No porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ResetKbc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + volatile UINT8 KbcSts = 0; + volatile UINT8 Buffer8; + UINT32 TimeOut = 0x100; + + // Reset KBC + if (CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ) != 0xff) { + // Clear KBC buffer + do { + Buffer8 = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_DATA ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + TimeOut--; + } while ((KbcSts & 3) && (TimeOut != 0)); + + + // Send BAT command + CpuIo->IoWrite8( PeiServices, CpuIo, KBC_IO_STS, 0xaa ); // 0x64 + + // IBFree + for (TimeOut = 0; TimeOut < 0x1000; TimeOut++) { + CpuIo->IoWrite8( PeiServices, CpuIo, IO_DELAY_PORT, KbcSts ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + if ((KbcSts & 2) == 0) break; + } + + // OBFree + for (TimeOut = 0; TimeOut < 0x500; TimeOut++) { + CpuIo->IoWrite8( PeiServices, CpuIo, IO_DELAY_PORT, KbcSts ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + if (KbcSts & 1) break; + } + + // Get result if needed + if (KbcSts & 1) + Buffer8 = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_DATA ); + } + + // Clear KBC status buffer. + KbcSts = CpuIo->IoRead8 ( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UpdateBootMode +// +// Description: This function determines the boot mode of the system. +// After the correct boot mode has been determined, the PEI +// Service function SetBootMode is called and then +// the MasterBootModePpi is installed +// +// Input: PeiServices - Pointer to the Pei Services function and +// data structure +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: Always returns EFI_SUCCESS +// Also defines the boot mode for the system +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS UpdateBootMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + // Check for changes in the possible boot modes. This should be made in + // prioritized order. At the end of this function the boot mode is + // determined. The EFI_BOOT_MODE is defined in the PEI Spec + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if (EFI_ERROR(Status) || (BootMode != BOOT_IN_RECOVERY_MODE)) + BootMode = BOOT_WITH_FULL_CONFIGURATION; + + // Returns 0 if no S3 resume detected returns -1 if this is an S3 boot + if (IsS3(PeiServices, CpuIo)) { + BootMode = BOOT_ON_S3_RESUME; + PEI_TRACE((-1,PeiServices, "Boot mode = BOOT_ON_S3_RESUME\n")); + } else { + // Check for S4 resume + if (IsS4(PeiServices, CpuIo)) { + BootMode = BOOT_ON_S4_RESUME; + PEI_TRACE((-1, PeiServices, "Boot mode = BOOT_ON_S4_RESUME\n")); + } + // Check for recovery mode + #if KBC_SUPPORT && Recovery_SUPPORT && PERFORM_KBC_RESET + ResetKbc(PeiServices, CpuIo, PciCfg); + #endif + + if (IsRecovery(PeiServices, PciCfg, CpuIo)) + BootMode = BOOT_IN_RECOVERY_MODE; + } + + if (IsCmosBad(PeiServices, CpuIo)) { + if (BootMode != BOOT_IN_RECOVERY_MODE){ + BootMode = BOOT_WITH_DEFAULT_SETTINGS; + PEI_TRACE((-1,PeiServices,"Boot mode = BOOT_WITH_DEFAULT_SETTING\n")); + } + +#if FORCE_USER_TO_SETUP_IF_CMOS_BAD // [EIP88358] >> +{ + EFI_STATUS Status; + UINT16 HobSize = sizeof(CMOS_BAD_HOB); + EFI_GUID CmosBadHobGuid = CMOS_BAD_HOB_GUID; + CMOS_BAD_HOB *CmosBadHob; + + Status = (*PeiServices)->CreateHob( PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + HobSize, + &CmosBadHob); + if(!EFI_ERROR(Status)) { + CmosBadHob->Header.Name = CmosBadHobGuid; + } +} +#endif // [EIP88358] << + } +#if Capsule2_0_SUPPORT + +#else + #if CAPSULE_SUPPORT + if (!EFI_ERROR(CheckIfCapsuleAvailable())) + BootMode = BOOT_ON_FLASH_UPDATE; + #endif +#endif + // Set the system BootMode + (*PeiServices)->SetBootMode(PeiServices, BootMode); + + // Let everyone know that boot mode has been determined by installing the + // MasterBootMode PPI + (*PeiServices)->InstallPpi(PeiServices, mBootModePpi ); + + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + if (BootMode == BOOT_IN_RECOVERY_MODE) // Recovery Boot Mode PPI + (*PeiServices)->InstallPpi( PeiServices, mRecoveryModePpi ); + + // [EIP87695]> +#if SYSTEM_REBOOT_NORMALLY_IF_S3_IS_FAILED + if (BootMode == BOOT_ON_S3_RESUME) //S3 Boot Mode PPI + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0xe3ff ); // Clear S3 for avoiding S3 resume twice +#endif + // <[EIP87695] + + return EFI_SUCCESS; +} + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DetectSataPortInfo +// +// Description: This function provides SATA Port Information +// +// Input: PeiServices - Pointer to the PEI services table +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID DetectSataPortInfo ( + IN EFI_PEI_SERVICES **PeiServices) +{ + EFI_STATUS Status; + UINT16 HobSize = sizeof(SATA_PRESENT_HOB); + EFI_GUID SataPresentHobGuid = AMI_SATA_PRESENT_HOB_GUID; + SATA_PRESENT_HOB *SataPresentHob; + UINT16 SataClassCode; + UINT8 SataPortStatus; + UINT8 SataPortEnable = 0; + SB_SETUP_DATA SbSetupData; + UINT8 i; + + Status = (*PeiServices)->CreateHob (PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + HobSize, + &SataPresentHob); + if(EFI_ERROR(Status)) return; + + SataPresentHob->EfiHobGuidType.Name = SataPresentHobGuid; + + for (i = 0; i < 4; i++) { + SataPresentHob->SataInfo[i].ClassCode = 0; + SataPresentHob->SataInfo[i].PresentPortBitMap = 0; + } + + // The SATA Mode Select should be configured in PchInitPeim. + SataClassCode = READ_PCI16_SATA(R_PCH_SATA_SUB_CLASS_CODE); + SataPresentHob->SataInfo[0].ClassCode = SataClassCode; + + if ((SataClassCode & 0xFF) == V_PCH_SATA_SUB_CLASS_CODE_IDE) { + // Lynx Point-LP didn't support IDE mode, so code should not enter here. + SataPortStatus = READ_PCI16_SATA(R_PCH_SATA_PCS) >> 8; + SataPresentHob->SataInfo[0].PresentPortBitMap = (SATA1_BDF << 16) | (SataPortStatus & 0xF); // Port 0~3 + SataPortStatus = READ_PCI16_SATA2(R_PCH_SATA_PCS) >> 8; + SataPresentHob->SataInfo[1].PresentPortBitMap = (SATA2_BDF << 16) | (SataPortStatus & 0x3); // Port 4~5 + SataPresentHob->SataInfo[1].ClassCode = SataClassCode; + SataPresentHob->ControllerCount = 2; + } else { // AHCI or Raid + GetSbSetupData (PeiServices, &SbSetupData, TRUE); + SataPortStatus = READ_PCI16_SATA(R_PCH_SATA_PCS) >> 8; + for (i = 0; i < GetPchMaxSataPortNum(); i++) { + // SataPort controll is done in DXE, so check Setup value here. + SataPortEnable |= (SbSetupData.SataPort[i] << i); + } + SataPortStatus &= SataPortEnable; + SataPresentHob->SataInfo[0].PresentPortBitMap = (SATA1_BDF << 16) | (SataPortStatus & 0x3F); // Port 0~5 + SataPresentHob->ControllerCount = 1; + } +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_Init +// +// Description: This function is the entry point for this PEI. This function +// initializes the chipset SB +// +// Input: FfsHeader - Pointer to the FFS file header +// PeiServices - Pointer to the PEI services table +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +// +// Notes: This function should initialize South Bridge for memory +// detection. +// Install AMI_PEI_SBINIT_POLICY_PPI to indicate that SB Init +// PEIM is installed +// Following things can be done at this point: +// - Enabling top of 4GB decode for full flash ROM +// - Programming South Bridge ports to enable access to +// South Bridge and other I/O bridge access +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI SBPEI_Init ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices ) +{ + EFI_STATUS Status; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_PEI_CPU_IO_PPI *CpuIo; + AMI_PEI_PCI_TABLE_INIT_PPI *AMIPCITableInit; + SB_SETUP_DATA SbSetupData; + AMI_GPIO_INIT_TABLE_STRUCT *pTable; + AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi = NULL; + PCH_SERIES PchSeries = GetPchSeries(); + + // Get pointer to the PCI config PPI + PciCfg = (*PeiServices)->PciCfg; + CpuIo = (*PeiServices)->CpuIo; + + PEI_PROGRESS_CODE (PeiServices, PEI_CAR_SB_INIT); + WRITE_IO8(PORTB_IO_CNTL, 0x0c); // Disable IOCHK NMI #, PCI SERR#. (0x61) + + // Locate AMI PCI Table Init PPI + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gAmiPEIPCITableInitPpiGuid, \ + 0, \ + NULL, \ + &AMIPCITableInit ); + + // Assert if not found - the AMI PCI Table Init PPI should exist + ASSERT_PEI_ERROR( PeiServices, Status ); + + GetSbSetupData( PeiServices, &SbSetupData, TRUE ); + +#if WdtPei_SUPPORT +{ + WDT_PPI *WdtPpi; + + // Locate WDT PPI for access to Wdt->Disable() + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gWdtPpiGuid, + 0, + NULL, + &WdtPpi + ); + if (!EFI_ERROR (Status)) { + WdtPpi->Disable(); + } +} +#endif + // Program Pch devices bar base + ProgramPchDeviceBase(PeiServices, PciCfg); + +#if SB_STALL_PPI_SUPPORT + // Install the SB Stall PPI + Status = (*PeiServices)->InstallPpi( PeiServices, \ + &mBeforeBootModePpiList[0] ); + ASSERT_PEI_ERROR( PeiServices, Status ); +#endif + + // Program Pch RCBA base + ProgramRCRBMmio(PeiServices, CpuIo); + + UpdateBootMode( PeiServices, CpuIo, PciCfg ); + + // Install PchPlatformPolicyPpi, it will notify to PchInitialize. + InstallPchPlatformPolicyPpi( PeiServices, &SbSetupData); + + //DeCode LPC IO + ProgramSBIoDecodeRegs( PeiServices, PciCfg); + + //Program GPIOs. + //Program the default GPIO Setting for chipset. +#if defined PROGRAM_DEFAULT_GPIO && PROGRAM_DEFAULT_GPIO == 1 + if (PchSeries == PchLp) { + pTable = stSB_GPIODefaultULTInitTable; + }else{ + pTable = stSB_GPIODefaultInitTable; + } + + ProgramGPIO( PeiServices, \ + CpuIo, \ + &SbSetupData, \ + pTable); +#endif + + //Program the OEM GPIO Setting for board. + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gAmiPeiSBCustomPpiGuid, \ + 0, \ + NULL, \ + &SBPeiOemPpi ); + + if (Status == EFI_SUCCESS) { + if (SBPeiOemPpi->GpioInit != NULL) { + pTable = SBPeiOemPpi->GpioInit->GpioTable; + ProgramGPIO( PeiServices, \ + CpuIo, \ + &SbSetupData, \ + pTable); + } + } else { + SBPeiOemPpi = NULL; + } + + // Program SB Devices' Subsystem Vendor ID & Subsystem ID + ProgramSBSubId( PeiServices, PciCfg, SBPeiOemPpi ); + + //Program PM Regs. + InitPMRegs(PeiServices, CpuIo, &SbSetupData); + + // General power failure handling + GeneralPowerFailureHandler(PeiServices, CpuIo, PciCfg); + + InitRTC( PeiServices, CpuIo ); + + // Set what state (S0/S5) to go to when power is re-applied after a power failure (G3 state) + SetTheStateToGoAfterG3(PeiServices, CpuIo, PciCfg, &SbSetupData); + + InitPCIe( PeiServices, CpuIo, PciCfg ); + + InitSMBus( PeiServices, CpuIo, PciCfg ); + + + // Install the SB Init Policy PPI + Status = (*PeiServices)->InstallPpi( PeiServices, &mPpiList[0] ); + ASSERT_PEI_ERROR( PeiServices, Status ); + + // Setup a SBPEI entry after PEI permantent memory be installed + + Status = (*PeiServices)->NotifyPpi( PeiServices, AfterMrcNotifyList ); + + Status = (*PeiServices)->NotifyPpi ( PeiServices, mMemoryReadyNotify ); + ASSERT_PEI_ERROR( PeiServices, Status ); + +#if defined iME_SUPPORT && iME_SUPPORT == 0 + if (!IsS3(PeiServices, CpuIo)) { + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, 0x20); // Clear Sleep Type + } +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramGPIO +// +// Description: This function initializes SB GPIOs +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramGPIO ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData, + IN AMI_GPIO_INIT_TABLE_STRUCT *pTable +) +{ + UINT16 i; + UINT32 OWN1; + UINT32 OWN2; + UINT32 OWN3; + UINT32 GPN_CFG1[96]; + UINT32 GPN_CFG2[96]; + UINT32 USE1_SEL; + UINT32 USE2_SEL; + UINT32 USE3_SEL; + UINT32 IO1_SEL; + UINT32 IO2_SEL; + UINT32 IO3_SEL; + UINT32 LVL1_SEL; + UINT32 LVL2_SEL; + UINT32 LVL3_SEL; + UINT32 INV1_SEL; + UINT32 RST1_SEL; + UINT32 RST2_SEL; + UINT32 RST3_SEL; + UINT32 BLNK_SEL; + UINT32 INT1_SEL; + UINT32 INT2_SEL; + UINT32 INT3_SEL; + UINT16 Offset; + UINT16 LpcDeviceId; + PCH_SERIES PchSeries = GetPchSeries(); + + LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + + if (pTable[0].GpioNo != 0xffff) { + if (PchSeries == PchLp) { + OWN1 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN1); // 0x00 + OWN2 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN2); // 0x04 + OWN3 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN3); // 0x08 + INT1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL1); // 0x90 + INT2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL2); // 0x94 + INT3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL3); // 0x98 + } else { + USE1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL); // 0x00 + IO1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL); // 0x04 + LVL1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL); // 0x0C + INV1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_INV); // 0x2C + + USE2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL2); // 0x30 + IO2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL2); // 0x34 + LVL2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL2); // 0x38 + + USE3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL3); // 0x40 + IO3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL3); // 0x44 + LVL3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL3); // 0x48 + } + BLNK_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPO_BLINK); // 0x18 + RST1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1); // 0x60 + RST2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL2); // 0x64 + RST3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL3); // 0x68 + + for (i = 0; pTable[i].GpioNo != 0xffff; i++) { + + Offset = pTable[i].GpioNo; + if (PchSeries == PchLp) { + GPN_CFG1[Offset] = READ_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*Offset)); // 0x100 + n*8h + GPN_CFG2[Offset] = READ_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG2 + GP_GPIO_CONFIG_SIZE*Offset)); // 0x104 + n*8h + + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT31)) | (pTable[i].GpioCfg.Fileds.LVL << 31); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT4)) | (pTable[i].GpioCfg.Fileds.LEB << 4); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT3)) | (pTable[i].GpioCfg.Fileds.INV << 3); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT2)) | (pTable[i].GpioCfg.Fileds.IO << 2); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(1)) | (pTable[i].GpioCfg.Fileds.USE); + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(BIT2)) | (pTable[i].GpioCfg.Fileds.DIS << 2); + //(EIP118667)>> + if(pTable[i].GpioCfg.Fileds.IO == 0 && pTable[i].GpioCfg.Fileds.USE == 1){ + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(BIT2)) | (BIT2); + } + //(EIP118667)<< + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(3)) | (pTable[i].GpioCfg.Fileds.WP); + } + + if (Offset < 32) { + if (PchSeries == PchLp) { + OWN1 = (OWN1 & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.OWN << Offset); + INT1_SEL = (INT1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.INT << Offset); + } else { + USE1_SEL = (USE1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.USE << Offset); + IO1_SEL = (IO1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.IO << Offset); + LVL1_SEL = (LVL1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.LVL << Offset); + INV1_SEL = (INV1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.INV << Offset); + } + RST1_SEL = (RST1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.RST << Offset); + BLNK_SEL = (BLNK_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.BLK << Offset); + } else if ((Offset >= 32) && (Offset < 64)) { + if (PchSeries == PchLp) { + OWN2 = (OWN2 & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.OWN << (Offset - 32)); + INT2_SEL = (INT2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.INT << (Offset - 32)); + } else { + USE2_SEL = (USE2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.USE << (Offset - 32)); + IO2_SEL = (IO2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.IO << (Offset - 32)); + LVL2_SEL = (LVL2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.LVL << (Offset - 32)); + } + RST2_SEL = (RST2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.RST << (Offset - 32)); + } else { + if (PchSeries == PchLp) { + OWN3 = (OWN3 & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.OWN << (Offset - 64)); + INT3_SEL = (INT3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.INT << (Offset - 64)); + } else { + USE3_SEL = (USE3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.USE << (Offset - 64)); + IO3_SEL = (IO3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.IO << (Offset - 64)); + LVL3_SEL = (LVL3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.LVL << (Offset - 64)); + } + RST3_SEL = (RST3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.RST << (Offset - 64)); + } + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*Offset), GPN_CFG1[Offset]); // 0x100 + n*8h + WRITE_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG2 + GP_GPIO_CONFIG_SIZE*Offset), GPN_CFG2[Offset]); // 0x104 + n*8h + } + } + + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN1, OWN1); // 0x00 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN2, OWN2); // 0x04 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN3, OWN3); // 0x08 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL1, INT1_SEL); // 0x90 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL2, INT2_SEL); // 0x94 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL3, INT3_SEL); // 0x98 + WRITE_IO32(GPIO_BASE_ADDRESS + GPI_IRQ_2_IOAPIC, GPI_IRQ_2_IOXAPIC); // 0x10 + } else { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL, USE1_SEL); // 0x00 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL, IO1_SEL); // 0x04 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL, LVL1_SEL); // 0x0C + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_INV, INV1_SEL); // 0x2C + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL2, USE2_SEL); // 0x30 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL2, IO2_SEL); // 0x34 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL2, LVL2_SEL); // 0x38 + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL3, USE3_SEL); // 0x40 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL3, IO3_SEL); // 0x44 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL3, LVL3_SEL); // 0x48 + } + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPO_BLINK, BLNK_SEL); // 0x18 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1, RST1_SEL); // 0x60 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL2, RST2_SEL); // 0x64 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL3, RST3_SEL); // 0x68 + } + + // BIOS implementation for SUS_PWR_DN_ACK + // As soon as platform BARs are initialized, BIOS must ensure that the following things + // are set high on all boot flows: + // (1) GPIO_BASE_ADDRESS + 0x60[30] + // (2) GPIO[30] pin (GPIO_BASE_ADDRESS + GP_LVL) (Done in GPIO.SDL) + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + SET_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1, BIT30); // 0x60 + } + // + // Now enable LANPHY_PC GPIO if LAN is enabled in the setup. + // Enabling this GPIO for all the boards. Both Red Fort and Buffalo Trail uses GPIO12 for this. + // Electric Peak does not use GPIO12, so changing the value for all boards should not effect + if (SbSetupData->PchLan) { + if (PchSeries == PchLp) { + SET_IO32 (GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*22), BIT31); // 0x190 + } else { + SET_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL, BIT12); // 0x0C + } + } + + // Clear GPI Status + if (PchSeries == PchLp) { + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS, 0xffff); // 0x80 + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS + 4, 0xffff); // 0x84 + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS + 8, 0xffff); // 0x88 + } else { + WRITE_IO16_PM(ACPI_IOREG_GPE0_STS + 2, 0xffff); // 0x22 + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsSBDevice +// +// Description: This function detimines SB PCI devices +// +// Input: UINT64 PciAddress +// UINT8 *PciSidReg +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS IsSBDevice( + IN UINT64 PciAddress, + IN OUT UINT8 *PciSidReg +) +{ + UINT8 i; + AMI_SB_PCI_DEVICES_TABLE_STRUCT PchDeviceTable[] = { HECI_BUS_DEV_FUN, ME_REG_SVID, + HECI2_BUS_DEV_FUN, ME_REG_SVID, + IDER_BUS_DEV_FUN, ME_REG_SVID, + KT_BUS_DEV_FUN, ME_REG_SVID, + XHCI_BUS_DEV_FUN, XHCI_REG_SVID, + LAN_BUS_DEV_FUN, LAN_REG_SVID, + EHCI2_BUS_DEV_FUN, EHCI_REG_SVID, + HDA_BUS_DEV_FUN, HDA_REG_SVID, + PCIEBRS_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS2_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS3_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS4_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS5_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS6_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS7_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS8_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIBR_BUS_DEV_FUN, PCIBR_REG_SVID, + EHCI_BUS_DEV_FUN, EHCI_REG_SVID, + SB_BUS_DEV_FUN, R_PCH_LPC_SS, + SATA_BUS_DEV_FUN, SATA_REG_SVID, + SMBUS_BUS_DEV_FUN, SMBUS_REG_SVID, + SATA2_BUS_DEV_FUN, SATA_REG_SVID, + THERMAL_BUS_DEV_FUN, R_PCH_LPC_SS + }; + UINT32 TableSize = sizeof(PchDeviceTable) / sizeof(AMI_SB_PCI_DEVICES_TABLE_STRUCT); + + for (i = 0; i < TableSize; i++) { + + if (PciAddress != PchDeviceTable[i].PciAddr) { + continue; + } else { + if (READ_PCI32((UINT8)(Shr64(PchDeviceTable[i].PciAddr, 24) & 0xff), \ + (UINT8)(Shr64(PchDeviceTable[i].PciAddr, 16) & 0xff), \ + (UINT8)(Shr64(PchDeviceTable[i].PciAddr, 8) & 0xff), \ + 0) == 0xffffffff) + return EFI_UNSUPPORTED; + + *PciSidReg = PchDeviceTable[i].PciSidReg; + return EFI_SUCCESS; + } + } + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBSubId +// +// Description: This function programs SB PCI devices sub-vendor ID and +// sub-system ID. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: VOID +// +// Notes: 1. This routine only programs the PCI device in SB, hence, we +// have to check the bus/device/function numbers whether they +// are a SB PCI device or not. +// 2. This routine is invoked by PEI phase.(After PEI permantent +// memory be installed) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramSBSubId ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i = 0; + UINT32 PciSid = 0xffffffff; + UINT8 PciSidReg = 0xff; + AMI_SB_PCI_SSID_TABLE_STRUCT DefaultSIdTbl[] = {SB_PCI_DEVICES_SSID_TABLE}; + AMI_SB_PCI_SSID_TABLE_STRUCT *SsidTblPtr = DefaultSIdTbl; + + if ((SBPeiOemPpi != NULL) && (SBPeiOemPpi->SsidTable != NULL)) + SsidTblPtr = SBPeiOemPpi->SsidTable; + + while (SsidTblPtr[i].PciAddr != 0xffffffffffffffff) { + if (IsSBDevice(SsidTblPtr[i].PciAddr, &PciSidReg) == EFI_SUCCESS) { + if (SsidTblPtr[i].Sid == 0xffffffff) { + Status = PciCfg->Read( PeiServices, + PciCfg, + EfiPeiPciCfgWidthUint32, + SsidTblPtr[i].PciAddr, + &PciSid); + } else { + PciSid = SsidTblPtr[i].Sid; + } + + if (SsidTblPtr[i].PciAddr == EHCI_BUS_DEV_FUN) + SET_PCI8_EHCI(R_PCH_EHCI_ACCESS_CNTL, 1); + else if (SsidTblPtr[i].PciAddr == EHCI2_BUS_DEV_FUN) + SET_PCI8_EHCI2(R_PCH_EHCI_ACCESS_CNTL, 1); + + Status = PciCfg->Write( PeiServices, + PciCfg, + EfiPeiPciCfgWidthUint32, + SsidTblPtr[i].PciAddr | PciSidReg, + &PciSid); + + if (SsidTblPtr[i].PciAddr == EHCI_BUS_DEV_FUN) + RESET_PCI8_EHCI(R_PCH_EHCI_ACCESS_CNTL, 1); + else if (SsidTblPtr[i].PciAddr == EHCI2_BUS_DEV_FUN) + RESET_PCI8_EHCI2(R_PCH_EHCI_ACCESS_CNTL, 1); + } + i++; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitPCIe +// +// Description: This function initializes SB PCI Express controller(s) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitPCIe ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSMBus +// +// Description: This function initializes SB SMBUS controller(s) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSMBus ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitUsbMisc +// +// Description: Miscellaneous USB initialization. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// BootMode - Boot Mode +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitUsbMisc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_BOOT_MODE BootMode +) +{ + PCH_SERIES PchSeries = GetPchSeries(); +#ifndef PEI_XHCI_MMIOBASE + UINT32 XhciMmioBase = 0xFE400000; //[EIP156783] +#else + UINT32 XhciMmioBase = PEI_XHCI_MMIOBASE; //[EIP115528] >> +#endif + UINT8 XhciCapLength; + UINT8 XhciMaxPorts; + UINT32 XhciPort; + EFI_PEI_STALL_PPI *StallPpi; + StallPpi = &mStallPpi; + +if ((BootMode == BOOT_IN_RECOVERY_MODE) || (BootMode == BOOT_ON_FLASH_UPDATE)) { + WRITE_PCI32( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x10, \ + XhciMmioBase); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x04, \ + 0x06); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB3PR, \ + 0x3F); + + //Add some delay to wait that device links are stable + StallPpi->Stall(PeiServices, StallPpi, 500 * 1000); + + XhciCapLength = READ_MEM8(XhciMmioBase); + if (PchSeries == PchH) { + switch ((READ_MEM8(XhciMmioBase + R_PCH_XHCI_FUS)) & B_PCH_XHCI_FUS_SSPRTCNT) { + case V_PCH_XHCI_FUS_SSPRTCNT_11B: + XhciMaxPorts = 0x0F; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_10B: + XhciMaxPorts = 0x11; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_01B: + XhciMaxPorts = 0x13; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_00B: + default: + XhciMaxPorts = 0x15; + break; + } + } else { + XhciMaxPorts = READ_MEM8(XhciMmioBase + 0x7); + } + //Clear each xHCI port power + for (XhciPort = 0; XhciPort < XhciMaxPorts; XhciPort++) { + RESET_MEM32(XhciMmioBase + XhciCapLength + 0x400 + (0x10 * XhciPort), BIT9); + } + // Set xHCI D0h & D8h as power-on default value. + WRITE_PCI16( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB2PR, \ + 0 ); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB3PR, \ + 0 ); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x04, \ + 0); + WRITE_PCI32( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x10, \ + 0); + } + + + // [EIP107424] [EIP123117]> + if (BootMode != BOOT_ON_S3_RESUME) { + // + // Clear unexpected USB EHCI Legacy Support Extended status. + // Set B0:D1A/1D:F0 Reg#6Ch[31:29] = '111b'. + // + WRITE_PCI32_EHCI ( R_PCH_EHCI_LEGEXT_CS, \ + B_PCH_EHCI_LEGEXT_CS_SMIBAR | \ + B_PCH_EHCI_LEGEXT_CS_SMIPCI | \ + B_PCH_EHCI_LEGEXT_CS_SMIOS); + if (PchSeries == PchH) { + WRITE_PCI32_EHCI ( R_PCH_EHCI_LEGEXT_CS, \ + B_PCH_EHCI_LEGEXT_CS_SMIBAR | \ + B_PCH_EHCI_LEGEXT_CS_SMIPCI | \ + B_PCH_EHCI_LEGEXT_CS_SMIOS); + } + } + // <[EIP107424] [EIP123117] + //[EIP115528]<< +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegAfterMemInstalled +// +// Description: This function can be used to program any SB regisater after +// PEI permantent memory be installed. +// +// Input: FfsHeader - Pointer to the desired FFS header. +// PeiServices - Pointer to the PEI services table. +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegAfterMemInstalled ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PEI_CPU_IO_PPI *CpuIo; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_BOOT_MODE BootMode; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + UINT32 SbAslBufVarPtr; + EFI_GUID SbAslBufPtrGuid = SB_ASL_BUFFER_PTR_GUID; + CHAR16 SbAslBufPtrVar[] = SB_ASL_BUFFER_PTR_VARIABLE; + + CpuIo = (*PeiServices)->CpuIo; + PciCfg = (*PeiServices)->PciCfg; + + PEI_PROGRESS_CODE (PeiServices, PEI_MEM_SB_INIT); + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + InitUsbMisc( PeiServices, CpuIo, PciCfg, BootMode ); + +#if (ACPI_SUPPORT) + if (BootMode == BOOT_ON_S3_RESUME) { + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gEfiPeiReadOnlyVariable2PpiGuid, \ + 0, \ + NULL, \ + &ReadOnlyVariable ); + ASSERT_PEI_ERROR( PeiServices, Status ); + VariableSize = sizeof(SbAslBufVarPtr); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, \ + SbAslBufPtrVar, \ + &SbAslBufPtrGuid, \ + NULL, \ + &VariableSize, \ + &SbAslBufVarPtr ); + if (!EFI_ERROR(Status)) { + // Update ACPI RTC status + RESET_MEM8(SbAslBufVarPtr, 1); // Clear ACPI RTC status + if (READ_IO16_PM(ACPI_IOREG_PM1_STS) & 0x400) + SET_MEM8(SbAslBufVarPtr, 1); // Set ACPI RTC status + } +#if defined BootScriptHide_SUPPORT && BootScriptHide_SUPPORT + //SCI_EN = 1 + SET_IO8_PM(ACPI_IOREG_PM1_CNTL, B_PCH_ACPI_PM1_CNT_SCI_EN); //PM1_CNT +#endif + } +#endif + // Clear Global Reset Bit + RESET_PCI32_SB(SB_REG_LPC_PMIR, B_ICH_LPC_PMIR_CF9GR); + + // Set up necessary PPI notifications after PEI permantent memory + // be installed + Status = (*PeiServices)->NotifyPpi( PeiServices, &mNotifyList[0] ); + ASSERT_PEI_ERROR ( PeiServices, Status ); + +#if defined RapidStart_SUPPORT && RapidStart_SUPPORT + if (BootMode == BOOT_ON_S4_RESUME) + if (RtcRead(FFS_NV_FLAG_REG) & BIT0) + return EFI_SUCCESS; +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegBeforeEndofPei +// +// Description: This function can be used to program any SB regisater before +// end of PEI phase. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegBeforeEndofPei ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PEI_CPU_IO_PPI *CpuIo; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_BOOT_MODE BootMode; + + CpuIo = (*PeiServices)->CpuIo; + PciCfg = (*PeiServices)->PciCfg; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + if (BootMode == BOOT_ON_S3_RESUME) { + // [EIP87695]> +#if SYSTEM_REBOOT_NORMALLY_IF_S3_IS_FAILED + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0xe3ff | (S3_SLP_TYP << 10)); // Clear S3 for avoiding S3 resume twice +#endif + // <[EIP87695] + // Porting if needed. + } else { + // Porting if needed. + } + + // Setting 8254 + // program timer 1 as refresh timer + IoWrite8(LEGACY_TIMER_CTRL,0x54); + IoWrite8(LEGACY_TIMER_1_COUNT,0x12); + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) + DetectSataPortInfo(PeiServices); +#endif + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsRtcUipAlwaysSet +// +// Description: Check RTC Time Update In Progress. +// +// Input: PeiServices - Pointer to the PEI services table +// +// Output: Boolean +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN IsRtcUipAlwaysSet( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + + EFI_PEI_STALL_PPI *StallPpi; + UINTN Count; + + StallPpi = &mStallPpi; + + for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500) + if ((READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_A_INDEX) & BIT07) == 0) { + return FALSE; + } + StallPpi->Stall (PeiServices, StallPpi, 3000); + } + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitRTC +// +// Description: This function initializes SB RTC related registers +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitRTC ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + UINT8 Buffer8; + UINT16 Buffer16; + BOOLEAN RtcUipIsAlwaysSet; + + // + // PCH BIOS Specification 0.6.0 - Section 19.2, "Power Failure Consideration" + // + // When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low. + // Software should clear this bit. For example, changing the RTC battery sets this bit. + // System BIOS should reset CMOS to default values if the RTC_PWR_STS is set. + // + // The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization. + // This will ensure that the RTC state machine has been initialized. + // 1. If the RTC_PWR_STS bit is set, which indicates a new coin-cell batttery + // insertion or a battery failure, steps 2 through 5 should be executed. + // 2. Set RTC Register 0Ah[6:4] to '110b' or '111b'. + // 3. Set RTC Register 0Bh[7]. + // 4. Set RTC Register 0Ah[6:4] to '010b'. + // 5. Clear RTC Register 0Bh[7]. + Buffer16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); // 0xA4 + RtcUipIsAlwaysSet = IsRtcUipAlwaysSet(PeiServices); + if ((Buffer16 & B_PCH_LPC_GEN_PMCON_RTC_PWR_STS) || RtcUipIsAlwaysSet) { + + // + // Step 1. + // BIOS clears this bit by writing a '0' to it. + // + if (Buffer16 & B_PCH_LPC_GEN_PMCON_RTC_PWR_STS) { + Buffer16 &= ~B_PCH_LPC_GEN_PMCON_RTC_PWR_STS; + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, Buffer16); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_DAY_OF_MONTH_REG), 0xFF); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_HOURS_REG), 0xFF); + } + + // + // Step 2. + // Set RTC Register 0Ah[6:4] to '110' or '111'. + // + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_A_INDEX), 0x66); + + // + // Step 3. + // Set RTC Register 0Bh[7]. + // + Buffer8 = (READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_B_INDEX) | 0x80); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_B_INDEX), Buffer8); + + // + // Step 4. + // Set RTC Register 0Ah[6:4] to '010'. + // + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_A_INDEX), 0x26); + + // + // Step 5. + // Clear RTC Register 0Bh[7]. + // + Buffer8 = (READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_B_INDEX) & ~0x80); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_B_INDEX), Buffer8); + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitPMRegs +// +// Description: This function initializes SB Power Management registers. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitPMRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_BOOT_MODE BootMode = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if (BootMode != BOOT_ON_S3_RESUME) { + WRITE_IO16_PM(ACPI_IOREG_PM1_EN, 0); + } + if (PchSeries == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c, 0); + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN, 0); + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN + 4, 0); + } + + // Clear Alternate GPI SMI Status Reg. + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS, 0xFFFFFFFF); + } else { + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, 0xFFFF); + } + +#if EHCI_CON_DISCON_WAKE_UP_SUPPORT + if (SbSetupData->EhciConDisConWakeUp) + RESET_MEM8_RCRB(RCRB_MMIO_RMHWKCTL , 0xFF); + else + SET_MEM8_RCRB(RCRB_MMIO_RMHWKCTL , (BIT00 | BIT01 | BIT04 | BIT05)); +#endif + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramRCRBMmio +// +// Description: This function initializes SB Root Complex registers +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramRCRBMmio ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + PCH_SERIES PchSeries = GetPchSeries(); + + //Enable IOAPIC Decoding and FERR# + if(PchSeries == PchLp){ + SET_MEM16_RCRB(R_PCH_RCRB_OIC, B_PCH_RCRB_OIC_AEN); + } else { + SET_MEM16_RCRB(R_PCH_RCRB_OIC, (B_PCH_RCRB_OIC_AEN | (PCH_RCRB_OIC_CEN << 9))); + } + + // Enable No Reboot, Boot BIOS Destination + SET_MEM32_RCRB(R_PCH_RCRB_GCS, (BIT06 | B_PCH_RCRB_GCS_NR)); + + SET_MEM32_RCRB (R_PCH_RCRB_FD2, BIT00); //0x3428 + + // PIRQ routing Info + // Device 31 Interrupt Pin, reg#3100h + WRITE_MEM32_RCRB(R_PCH_RCRB_D31IP, (RCRB_IRQB << 8) + + (RCRB_IRQC << 12) + + (RCRB_IRQD << 16) + + (RCRB_IRQB << 20) + + (RCRB_IRQC << 24)); + + // Device 30 Interrupt Pin, reg#3104h - Read Only + + // Device 29 Interrupt Pin, reg#3108h + WRITE_MEM32_RCRB(R_PCH_RCRB_D29IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12) + + (RCRB_IRQA << 16)); + + // Device 28 Interrupt Pin, reg#310Ch + WRITE_MEM32_RCRB(R_PCH_RCRB_D28IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12) + + (RCRB_IRQA << 16) + + (RCRB_IRQB << 20) + + (RCRB_IRQC << 24) + + (RCRB_IRQD << 28)); + + // Device 27 Interrupt Pin, reg#3110h + WRITE_MEM32_RCRB(R_PCH_RCRB_D27IP, (RCRB_IRQA << 0)); + + // Device 26 Interrupt Pin, reg#3114h + WRITE_MEM32_RCRB(R_PCH_RCRB_D26IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12)); + + // Device 25 Interrupt Pin, reg#3118h + WRITE_MEM32_RCRB(R_PCH_RCRB_D25IP, (RCRB_IRQA << 0)); + + // Device 22 Interrupt Pin, reg#3124h + WRITE_MEM16_RCRB(R_PCH_RCRB_D22IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQB << 12)); + + // Device 20 Interrupt Pin, reg#3128h + WRITE_MEM32_RCRB(R_PCH_RCRB_D20IP, (RCRB_IRQA << 0)); + + // Device 31 Interrupt Route, reg#3140h + WRITE_MEM16_RCRB(R_PCH_RCRB_D31IR, (RCRB_PIRQD << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQA << 12)); + + // Device 29 Interrupt Route, reg#3144h + WRITE_MEM16_RCRB(R_PCH_RCRB_D29IR, (RCRB_PIRQH << 0) + + (RCRB_PIRQD << 4) + + (RCRB_PIRQA << 8) + + (RCRB_PIRQC << 12)); + + // Device 28 Interrupt Route, reg#3146h + WRITE_MEM16_RCRB(R_PCH_RCRB_D28IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 27 Interrupt Route, reg#3148h + WRITE_MEM16_RCRB(R_PCH_RCRB_D27IR, (RCRB_PIRQG << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 26 Interrupt Route, reg#314Ch + WRITE_MEM16_RCRB(R_PCH_RCRB_D26IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQF << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 25 Interrupt Route, reg#3150h + WRITE_MEM16_RCRB(R_PCH_RCRB_D25IR, (RCRB_PIRQE << 0) + + (RCRB_PIRQF << 4) + + (RCRB_PIRQG << 8) + + (RCRB_PIRQH << 12)); + + if (PchSeries == PchLp) { + // Device 23 Interrupt Route, reg#3158h + WRITE_MEM16_RCRB(R_PCH_RCRB_D23IR, (RCRB_PIRQG << 0)); + } + + // Device 22 Interrupt Route, reg#315Ch + WRITE_MEM16_RCRB(R_PCH_RCRB_D22IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQD << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQB << 12)); + + if (PchSeries == PchLp) { + // Device 21 Interrupt Route, reg#3164h + WRITE_MEM16_RCRB(R_PCH_RCRB_D21IR, (RCRB_PIRQE << 0) + + (RCRB_PIRQE << 4) + + (RCRB_PIRQF << 8) + + (RCRB_PIRQF << 12)); + } + + // Device 20 Interrupt Route, reg#3160h + WRITE_MEM16_RCRB(R_PCH_RCRB_D20IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + if (PchSeries == PchLp) { + // Device 19 Interrupt Route, reg#3168h + WRITE_MEM16_RCRB(R_PCH_RCRB_D19IR, (RCRB_PIRQH << 0)); + } + + // EIP176923 + #if defined DISABLE_DAYLIGHT_SAVINGS && DISABLE_DAYLIGHT_SAVINGS == 1 + SET_MEM16_RCRB(R_PCH_RCRB_BUC, B_PCH_RCRB_BUC_SDO); + #endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBIoDecodeRegs +// +// Description: This function initializes SB IO Decide Registers. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +ProgramSBIoDecodeRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + +#if defined EMUL6064_SUPPORT && EMUL6064_SUPPORT == 1 + // Force KBC_LPC_EN bit (B0:D31:F0 Reg 82h[10]) = 1 if EMUL6064_SUPPORT = 1. + SbLib_SetLpcDeviceDecoding(NULL, 0x60, 0, dsPS2K); +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramPchDeviceBase +// +// Description: This function initializes SB Devices Base +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +ProgramPchDeviceBase ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + + // Program RCBA Base + WRITE_PCI32_SB(SB_REG_RCBA, SB_RCRB_BASE_ADDRESS | 1);//0xF0 + + // Write Heci Base Address and enable Heci device + WRITE_PCI32_HECI(ME_REG_HECI_MBAR, HECI_BASE_ADDRESS); + WRITE_PCI16_HECI(ME_REG_PCICMD, 0x06); + + // Write Heci Base Address and enable Heci device + WRITE_PCI32_HECI2(ME_REG_HECI_MBAR, HECI2_BASE_ADDRESS); + WRITE_PCI16_HECI2(ME_REG_PCICMD, 0x06); + + // Program PM Base + WRITE_PCI16_SB(SB_REG_PMBASE, PM_BASE_ADDRESS); + WRITE_PCI8_SB(SB_REG_ACPI_CNTL, 0x80); + + // Program GPIO Base + WRITE_PCI16_SB(SB_REG_GPIOBASE, GPIO_BASE_ADDRESS); + WRITE_PCI8_SB(SB_REG_GC, 0x10); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GeneralPowerFailureHandler +// +// Description: When the PWR_FLR bit is set, it indicates the trickle power +// from the main battery or tricle supply failed while in suspend +// or since last boot. This bit us ub the RTC well and is cleared +// only by RTCRST#. Software writes a "1" to clear this bit. +// System BIUOS should follow cold boot path if PWR_FLR, GEN_RST_STS +// or PWRBTNOR_STS is set to 1 regardless of the value in the SLP_TYP +// field. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +GeneralPowerFailureHandler ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + + UINT16 DataUint16; + UINT8 DataUint8; + + // + // PCH BIOS Specification 0.6.0 - Section 19.2, "Power Failure Considerations" + // + // When the PWR_FLR bit is set, it indicates the trickle power from the main + // battery or tricle supply failed while in suspend or since last boot. + // System BIOS should follow cold boot path if PWR_FLR, GEN_RST_STS or + // PWRBTNOR_STS is set to 1 regardless of the value in the SLP_TYP field. + // + DataUint16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); + if ((DataUint16 & (B_PCH_LPC_GEN_PMCON_GEN_RST_STS | B_PCH_LPC_GEN_PMCON_PWR_FLR)) || \ + (READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_PRBTNOR)) { + // + // BIOS clears these bits by writing a '1' to them. + // + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, DataUint16); + WRITE_IO16_PM(R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PRBTNOR); + + // + // Clear Wake Status (WAK_STS) and Sleep Type (SLP_TYP) + // + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, B_PCH_ACPI_PM1_STS_WAK); + DataUint16 = (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & ~B_PCH_ACPI_PM1_CNT_SLP_TYP); + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, DataUint16); + } + + // + // When the CPUPWR_FLR bit is set, it indicates VRMPWRGD signal from + // the CPU VRM went low. This bit is now set if VRMPWRGD goes low + // during Intel (R) SpeedStep Technology transition. + // Software must clear this bit if set. + // + DataUint8 = READ_PCI8_SB(R_PCH_LPC_GEN_PMCON_2); + if (DataUint8 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) { + // + // BIOS clears this bit by writing a '0' to it. + // + DataUint8 &= ~B_PCH_LPC_GEN_PMCON_SYSPWR_FLR; + WRITE_PCI8_SB(R_PCH_LPC_GEN_PMCON_2, DataUint8); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetTheStateToGoAfterG3 +// +// Description: Set what state (S0/S5) to go to when power is re-applied +// after a power failure (G3 state) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// SbSetupData - Pointer to the SbSetupData +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +SetTheStateToGoAfterG3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN SB_SETUP_DATA *SbSetupData +) +{ + UINT16 DataUint16; + // + // Make sure we have a setup data, if not, just return. + // + if (SbSetupData == NULL) { + return EFI_UNSUPPORTED; + } + + DataUint16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); + if(SbSetupData->LastState == 0) { + DataUint16 |= B_PCH_LPC_GEN_PMCON_AFTERG3_EN; + } else { + DataUint16 &= ~B_PCH_LPC_GEN_PMCON_AFTERG3_EN; + } + +// Done in PchMisc.c +//#### DataUint16 |= (SbSetupData->SlpS4AssW << 4); + + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, DataUint16); + + return EFI_SUCCESS; +} + +static UINT8 mSmbusRsvdAddresses[DIMM_SLOT_NUM] = { + DIMM1_SMBUS_ADDRESS, + DIMM2_SMBUS_ADDRESS, + DIMM3_SMBUS_ADDRESS, + DIMM4_SMBUS_ADDRESS +}; + +static PEI_SMBUS_POLICY_PPI mSmbusPolicyPpi = { + SMBUS_BASE_ADDRESS, + SMBUS_BUS_DEV_FUN, + DIMM_SLOT_NUM, + mSmbusRsvdAddresses +}; + +EFI_PEI_PPI_DESCRIPTOR SmbusPolicy_PpiDescriptor = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiSmbusPolicyPpiGuid, + &mSmbusPolicyPpi +}; + // [EIP106687]> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbPcieDetectNonComplaintPcieDevice +// +// Description: +// +// Input: IN UINT8 Index, +// IN PCH_PCIE_CONFIG *PcieConfig +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +SbPcieDetectNonComplaintPcieDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT8 Index, + IN PCH_PCIE_CONFIG *PcieConfig, + IN SB_SETUP_DATA *SbSetupData +) +{ + if ((PcieConfig->PcieSpeed[Index] == PchPcieAuto) && \ + (SbSetupData->PcieRootPortEn[Index]!= 0)) + { + PEI_TRACE((-1,PeiServices, "Enhance Detect Non-Compliance PCIE Device @B:0|D:1C|F:%x Start .\n", Index)); + // Assign temp bus + PEI_TRACE((-1,PeiServices, "Assign temp bus ...\n")); + WRITE_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_BNUM+1, 0x0101); + // Do a dummy Write + WRITE_PCI32(1, 0, 0, PCI_VID, 0x12345678); + + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Can't find Device... Retrain device first.\n")); + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_LD); + CountTime((RETRAIN_DELAY * 10), PM_BASE_ADDRESS); //delay 500us + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_RL); + CountTime((RETRAIN_DELAY * 8000), PM_BASE_ADDRESS); //delay 400ms + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Still can't find Device in Gen2 Speed... Speed is setted in Gen1 and delay 200 ms.\n")); + // Set Speed to Gen1 + RW_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL2, 0x01, 0x03); + CountTime((RETRAIN_DELAY * 4000), PM_BASE_ADDRESS); //delay 200ms + + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Still can't find Device in Gen1 Speed... Retrain device again !!!\n")); + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_LD); + CountTime((RETRAIN_DELAY * 10), PM_BASE_ADDRESS); //delay 500us + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_RL); + CountTime((RETRAIN_DELAY * 8000), PM_BASE_ADDRESS); //delay 400ms + + if (READ_PCI16(1, 0, 0, PCI_VID) != 0xFFFF) PcieConfig->PcieSpeed[Index] = PchPcieGen1; + } + else PcieConfig->PcieSpeed[Index] = PchPcieGen1; + } + } + + // Remove temp bus + PEI_TRACE((-1,PeiServices, "Remove temp bus.\n")); + WRITE_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, Index, PCI_PBUS, 0xFF000000); + + PEI_TRACE((-1,PeiServices, "Enhance Detect Non-Compliance PCIE Device end.\n")); + } +} + // <[EIP106687] +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InstallPchPlatformPolicyPpi +// +// Description: Install Pch Platform Policy Ppi +// +// Input: IN EFI_PEI_SERVICES **PeiServices, +// IN SB_SETUP_DATA *SbSetupData +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallPchPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +) +{ + + UINT8 *SbRcba = (UINT8*)(UINTN)SB_RCRB_BASE_ADDRESS; + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc; + PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi; + PCH_THERMAL_MANAGEMENT *ThermalMgmt; + PCH_MEMORY_THROTTLING *MemoryThrottling; + PCH_HPET_CONFIG *HpetConfig; + PCH_IOAPIC_CONFIG *IoApicConfig; + PCH_SATA_CONTROL *SataConfig; + PCH_SATA_TRACE_CONFIG *SataTraceConfig; + PCH_GBE_CONFIG *GbeConfig; + PCH_PCIE_CONFIG *PcieConfig; + PCH_USB_CONFIG *UsbConfig; + EFI_BOOT_MODE BootMode; + UINT8 Index; + PCH_PLATFORM_DATA *PlatformData; + UINT16 LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + UINT16 Data16; + UINT8 PortIndex; + UINT16 UsbPortLength[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORTS_LENGTH}; + UINT8 UsbPortLocation[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORT_LOCATION_CONFIG}; + UINT8 UsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_OVER_CURRENT_MAPPING_SETTINGS}; + UINT8 Usb30OverCurrentMapping[LPTH_XHCI_MAX_USB3_PORTS] = {USB30_OVER_CURRENT_MAPPING_SETTINGS}; + PCH_SERIES PchSeries = GetPchSeries(); + SATA_LENGTH_CONFIG SataLengthConfigTable[] = {SATA_PORT1_LENGTH_CONFIG, + SATA_PORT2_LENGTH_CONFIG, + SATA_PORT3_LENGTH_CONFIG, + SATA_PORT4_LENGTH_CONFIG, + SATA_PORT5_LENGTH_CONFIG, + SATA_PORT6_LENGTH_CONFIG}; +#if defined iME_SUPPORT && iME_SUPPORT + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetupData; + EFI_GUID EfiMeBiosExtensionSetupGuid = EFI_ME_BIOS_EXTENSION_SETUP_GUID; + CHAR16 EfiMeBiosExtensionSetupName[] = EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME; +#endif + + BootMode = BOOT_WITH_FULL_CONFIGURATION; + + // Install SmbusPolicy PPI + Status = (**PeiServices).InstallPpi (PeiServices, &SmbusPolicy_PpiDescriptor); + ASSERT_PEI_ERROR (PeiServices, Status); + + // Allocate descriptor and PPI structures. Since these are dynamically updated + // we cannot do a global variable PPI. + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), &PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PchPlatformPolicyPpiDesc, sizeof (EFI_PEI_PPI_DESCRIPTOR), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), &PchPlatformPolicyPpi); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PchPlatformPolicyPpi, sizeof (PCH_PLATFORM_POLICY_PPI), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), &HpetConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) HpetConfig, sizeof (PCH_HPET_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_THERMAL_MANAGEMENT), &ThermalMgmt); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) ThermalMgmt, sizeof (PCH_THERMAL_MANAGEMENT), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), &IoApicConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) IoApicConfig, sizeof (PCH_IOAPIC_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_MEMORY_THROTTLING), &MemoryThrottling); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) MemoryThrottling, sizeof (PCH_MEMORY_THROTTLING), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_SATA_CONTROL), &SataConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) SataConfig, sizeof (PCH_SATA_CONTROL), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_SATA_TRACE_CONFIG), &SataTraceConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) SataTraceConfig, sizeof (PCH_SATA_TRACE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_GBE_CONFIG), &GbeConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) GbeConfig, sizeof (PCH_GBE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), &PcieConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PcieConfig, sizeof (PCH_PCIE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_DATA), &PlatformData); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PlatformData, sizeof (PCH_PLATFORM_DATA), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), &UsbConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) UsbConfig, sizeof (PCH_USB_CONFIG), 0); + + PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_4; + PchPlatformPolicyPpi->BusNumber = 0; + PchPlatformPolicyPpi->Rcba = SB_RCRB_BASE_ADDRESS; + PchPlatformPolicyPpi->PmBase = PM_BASE_ADDRESS; + PchPlatformPolicyPpi->GpioBase = GPIO_BASE_ADDRESS; + PchPlatformPolicyPpi->Port80Route = RESERVED_PAGE_ROUTE; + + PchPlatformPolicyPpi->GbeConfig = GbeConfig; + PchPlatformPolicyPpi->ThermalMgmt = ThermalMgmt; + PchPlatformPolicyPpi->HpetConfig = HpetConfig; + PchPlatformPolicyPpi->SataConfig = SataConfig; + PchPlatformPolicyPpi->PcieConfig = PcieConfig; + PchPlatformPolicyPpi->IoApicConfig = IoApicConfig; + PchPlatformPolicyPpi->PlatformData = PlatformData; + PchPlatformPolicyPpi->UsbConfig = UsbConfig; + +//- ThermalMgmt->ThermalBaseB = SB_THERMAL_BASE_ADDRESS; + ThermalMgmt->MemoryThrottling = MemoryThrottling; + + GbeConfig->EnableGbe = 1; +//- GbeConfig->GbeMemBaseAddr = 0xFFFF8000; //PCH_LAN_MBARB_BASE_ADDRESS; + + for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) + PcieConfig->PcieSpeed[Index] = PchPcieAuto; + + HpetConfig->Enable = PCH_DEVICE_ENABLE; + HpetConfig->Base = HPET_BASE_ADDRESS; + + + IoApicConfig->IoApicId = PCH_IO_APIC_ID; + IoApicConfig->ApicRangeSelect = PCH_APIC_RANGE_SELECT; + IoApicConfig->IoApicEntry24_39 = PCH_DEVICE_ENABLE; + + if(SbSetupData != NULL) { + GbeConfig->EnableGbe = SbSetupData->PchLan; + + if ((READ_MEM16_RCRB(R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { + RESET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)); + SET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9)); + if ((READ_MEM32_RCRB (R_PCH_SPI_FDOD) & B_PCH_SPI_STRP9_GBE_PCIE_EN) == 0) { + GbeConfig->EnableGbe = PCH_DEVICE_DISABLE; + } + } + + PchPlatformPolicyPpi->Port80Route = SbSetupData->Port80Route; // 0 - Forward to LPC. 1 - Forward to PCI. + SataConfig->SataMode = SbSetupData->SataInterfaceMode; + SataConfig->SataTraceConfig = SataTraceConfig; +// HpetConfig->Enable = SbSetupData->Hpet; // Force HPET enabled for MRC initialization. + // [EIP106687]> + for (Index = 0; Index < GetPchMaxPciePortNum (); Index++){ + PcieConfig->PcieSpeed[Index] = SbSetupData->PcieRootPortSpeed[Index]; + + //Enhance Detect Non-Compliance PCIE Device + if ((SbSetupData->PcieRPDetectNonComplaint[Index] == 1) && (SbSetupData->PcieRootPortEn[0]!= 0)) + SbPcieDetectNonComplaintPcieDevice(PeiServices, Index, PcieConfig, SbSetupData); + } + // <[EIP106687] + //In case of recovery change the SATA mode to IDE + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if(BootMode == BOOT_IN_RECOVERY_MODE) { + SataConfig->SataMode = PchSataModeIde; + } + + SataTraceConfig->TestMode = PCH_DEVICE_DISABLE; + PEI_TRACE((-1,PeiServices, "SBPei SATA RxEq Policy setting:\n")); + for( PortIndex = 0; PortIndex < GetPchMaxSataPortNum(); PortIndex++ ) { + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].Enable = SataLengthConfigTable[PortIndex].SataGen1RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].Enable = SataLengthConfigTable[PortIndex].SataGen2RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].Enable = SataLengthConfigTable[PortIndex].SataGen3RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].RxEq = SataLengthConfigTable[PortIndex].SataGen1RxEqValue; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].RxEq = SataLengthConfigTable[PortIndex].SataGen2RxEqValue; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].RxEq = SataLengthConfigTable[PortIndex].SataGen3RxEqValue; + PEI_TRACE((-1,PeiServices, "SATA Port%x: %x %x %x %x %x %x\n", PortIndex,\ + SataLengthConfigTable[PortIndex].SataGen1RxEqEnable, SataLengthConfigTable[PortIndex].SataGen1RxEqValue,\ + SataLengthConfigTable[PortIndex].SataGen2RxEqEnable, SataLengthConfigTable[PortIndex].SataGen2RxEqValue,\ + SataLengthConfigTable[PortIndex].SataGen3RxEqEnable, SataLengthConfigTable[PortIndex].SataGen3RxEqValue)); + } + // + // Thermal configuration - Initialize policy to SETUP values. + // +#if defined iME_SUPPORT && iME_SUPPORT + MemoryThrottling->Enable = SbSetupData->TrEnabled; +#else + MemoryThrottling->Enable = PCH_DEVICE_DISABLE; +#endif + MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable = TSGPIO_C_PMSYN; + MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable = TSGPIO_D_PMSYN; + MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable = TSGPIO_C_C0_TRANSMIT; + MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable = TSGPIO_D_C0_TRANSMIT; + MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection = TSGPIO_C_PIN_SEL; + MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection = TSGPIO_D_PIN_SEL; + /// + /// UsbConfig should be initialized based on platform configuration if UsbPrecondition feature is + /// enabled. Otherwise, the remaining data of UsbConfig can stay in zero. + /// + UsbConfig->UsbPrecondition = SbSetupData->UsbPrecondition; +#ifdef RAPID_START_FLAG + if (RapidStartResumeCheck () == TRUE) { + /// + /// This is RapidStart resume, skip the UsbPrecondition feature in PEI phase + /// + UsbConfig->UsbPrecondition = 0; + } +#endif + +#ifdef USB_PRECONDITION_ENABLE_FLAG + /// + /// Update Precondition option for S4 resume. + /// Skip Precondition for S4 resume in case this boot may not connect BIOS USB driver. + /// If BIOS USB driver will be connected always for S4, then disable below update. + /// To keep consistency during boot, must enabled or disabled below function in both PEI and DXE + /// PlatformPolicyInit driver. + /// + if (UsbConfig->UsbPrecondition == TRUE) { + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if ((BootMode == BOOT_ON_S4_RESUME) || (BootMode == BOOT_IN_RECOVERY_MODE)){ + UsbConfig->UsbPrecondition = FALSE; + PEI_TRACE((-1,PeiServices, "BootMode is BOOT_ON_S4_RESUME or BOOT_IN_RECOVERY_MODE, disable Precondition")); + } + } +#endif // USB_PRECONDITION_ENABLE_FLAG + + if (UsbConfig->UsbPrecondition) { +#if defined iAMT_SUPPORT && iAMT_SUPPORT + UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; + UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; +#else + UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; + UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; +#endif + +#if defined iME_SUPPORT && iME_SUPPORT + Status = (*PeiServices)->LocatePpi( PeiServices, + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + &ReadOnlyVariable ); + if (ReadOnlyVariable != NULL) { + VariableSize = sizeof (MeBiosExtensionSetupData); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, + EfiMeBiosExtensionSetupName, + &EfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBiosExtensionSetupData ); + if (!EFI_ERROR (Status)) { + UsbConfig->Ehci1Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + UsbConfig->Ehci2Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + } + } +#endif + + UsbConfig->Usb20Settings[0].Enable = SbSetupData->PchUsb20[0]; + if (PchSeries == PchLp) { + // [ EIP219399 ] + //UsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS]=ULT_USB_OVER_CURRENT_MAPPING_SETTINGS; + UINT8 UltUsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS] = {ULT_USB_OVER_CURRENT_MAPPING_SETTINGS}; + (*PeiServices)->CopyMem(UsbOverCurrentMapping, UltUsbOverCurrentMapping, LPTH_USB_MAX_PHYSICAL_PORTS); + + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } else { + UsbConfig->Usb20Settings[1].Enable = SbSetupData->PchUsb20[1]; + } + + if ((UsbConfig->Usb20Settings[0].Enable == PCH_DEVICE_DISABLE) && + (UsbConfig->Usb20Settings[1].Enable == PCH_DEVICE_DISABLE)) { + UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE; + if (PchSeries == PchLp) { + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_ENABLE; + } + } + + UsbConfig->UsbPerPortCtl = SbSetupData->PchUsbPerPortCtl; + + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + if (SbSetupData->PchUsbPerPortCtl != PCH_DEVICE_DISABLE) { + UsbConfig->PortSettings[PortIndex].Enable = SbSetupData->PchUsbPort[PortIndex]; + } else { + UsbConfig->PortSettings[PortIndex].Enable = PCH_DEVICE_ENABLE; + } + + UsbConfig->Usb20OverCurrentPins[PortIndex] = UsbOverCurrentMapping[PortIndex]; + UsbConfig->PortSettings[PortIndex].Usb20PortLength = UsbPortLength[PortIndex]; + UsbConfig->PortSettings[PortIndex].Location = UsbPortLocation[PortIndex]; + + if (PchSeries == PchH) { + if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId)) { + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; //Back Panel + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 3; //Front Panel + } + + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x80) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 7.9" + } else if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x130) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 8"-12.9" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 4; //Back Panel, 13" onward + } + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Front Panel + } + } else if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } + + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } + } + } else if (PchSeries == PchLp) { + if ((UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } + + if ((UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } + } + } + + UsbConfig->Usb30Settings.Mode = SbSetupData->PchUsb30Mode; + + // + // Automatically disable EHCI when XHCI Mode is Enabled to save power. + // + if (UsbConfig->Usb30Settings.Mode == 1) { + UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_DISABLE; + if (PchSeries == PchH) { + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } + } + + if (SbSetupData->PchUsb30Mode == 3) { + UsbConfig->Usb30Settings.PreBootSupport = 1; + } else { + UsbConfig->Usb30Settings.PreBootSupport = SbSetupData->PchUsb30PreBootSupport; + } + + if (SbSetupData->PchUsb30Mode == 4) { + UsbConfig->Usb30Settings.Mode = 2; + UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_ENABLE; + } else { + UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_DISABLE; + } + + // + // XhciIdleL1 can be set to disable for LPT-LP Ax stepping to workaround USB3 hot plug will fail after 1 hot plug removal. + // + UsbConfig->Usb30Settings.XhciIdleL1 = SbSetupData->PchUsb30IdleL1; + + // + // Btcg is for enabling/disabling trunk clock gating. + // + UsbConfig->Usb30Settings.Btcg = SbSetupData->PchUsb30Btcg; + + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + if (SbSetupData->PchUsb20PinRoute == 1){ + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 0; + } else if (SbSetupData->PchUsb20PinRoute == 2){ + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 1; + } else { + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = SbSetupData->ManualModeUsb20PerPinRoute[PortIndex]; + } + } + + for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) { + if (SbSetupData->PchUsb30PinEnable == 1){ + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 0; + } else if (SbSetupData->PchUsb30PinEnable == 2){ + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 1; + } else { + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = SbSetupData->ManualModeUsb30PerPinEnable[PortIndex]; + } + UsbConfig->Usb30OverCurrentPins[PortIndex] = Usb30OverCurrentMapping[PortIndex]; + } + } // if (UsbConfig->UsbPrecondition) + + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + // Save R_PCH_LPC_ENABLES in Data16. + Data16 = READ_PCI16_SB(R_PCH_LPC_ENABLES); + + if (!(Data16 & B_PCH_LPC_ENABLES_MC_EN)) + SET_PCI16_SB(R_PCH_LPC_ENABLES, B_PCH_LPC_ENABLES_MC_EN); + + if (READ_IO8(0x66) != 0xFF) PlatformData->EcPresent = 1; + + // Restore R_PCH_LPC_ENABLES. + WRITE_PCI16_SB(R_PCH_LPC_ENABLES, Data16); + } + + } // (SbSetupData != NULL) + + /// + /// PlatformData->SmmBwp value directly depends on the value of CpuConfig->Pfat + /// (found in CpuPolicyInitPei.c file) + /// If CpuConfig->Pfat is set to 1 (enabled) then + /// PlatformData->SmmBwp has to be set to 1 (enabled) + /// This is a PFAT Security requirement that needs to be addressed + /// If CpuConfig->Pfat is set to 0 (disabled) then + /// PlatformData->SmmBwp value don't care, it can be set to either + /// 1 (enabled) or 0 (disabled) based on customer implementation + /// + PlatformData->SmmBwp = 0; + + /// + /// Temporary Memory Base Address for PCI devices to be used to initialize MMIO registers. + /// Minimum size is 64KB bytes. + /// + PlatformData->TempMemBaseAddr = SB_TEMP_MMIO_BASE; + + PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi; + + // + // Install OEM PCH Platform Policy Override PPI + // + PchPlatformPolicyPpiDesc->Guid = &gOemPchPlatformPolicyOverridePpiGuid; + Status = (**PeiServices).InstallPpi (PeiServices, PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + + // + // Install PCH Platform Policy PPI + // + PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid; + Status = (**PeiServices).InstallPpi (PeiServices, PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + + // [EIP120438]> + if ((HpetConfig->Enable) && (HpetConfig->Base != 0)) { + WRITE_MEM32(HpetConfig->Base + 0xF0, 0); + } + // <[EIP120438] + + return EFI_SUCCESS; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegAfterMrc +// +// Description: This function can be used to program any SB regisater after +// memory is detected. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegAfterMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + IN EFI_BOOT_MODE BootMode; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + EFI_GUID WarmResetGuid = SB_WARM_RESET_GUID; + CHAR16 WarmResetVar[] = SB_WARM_RESET_VARIABLE; + UINT32 WarmResetFlag = 0; +#if Capsule2_0_SUPPORT + PEI_CAPSULE_PPI *Capsule; +#endif + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): Start.\n")); + + Status = (*PeiServices)->GetBootMode( PeiServices, &BootMode ); + + if (BootMode == BOOT_ON_S3_RESUME) { + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): S3 Resume.\n")); + + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gEfiPeiReadOnlyVariable2PpiGuid, \ + 0, \ + NULL, \ + &ReadOnlyVariable ); + if (!EFI_ERROR(Status)) { + VariableSize = sizeof(WarmResetFlag); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, \ + WarmResetVar, \ + &WarmResetGuid, \ + NULL, \ + &VariableSize, \ + &WarmResetFlag ); + if (WarmResetFlag == SB_WARM_RESET_TAG) { + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): Update BootMode.\n")); + BootMode = BOOT_WITH_FULL_CONFIGURATION; + +#if Capsule2_0_SUPPORT + // + // Update BootMode, if Capsule 2.0 PPI is available. + // + Status = (*PeiServices)->LocatePpi ( PeiServices, \ + &gPeiCapsulePpiGuid, \ + 0, \ + NULL, \ + &Capsule); + + if (!EFI_ERROR(Status)) { + BootMode = BOOT_ON_FLASH_UPDATE; + Status = (*PeiServices)->NotifyPpi( PeiServices, EndOfMrcNotifyList ); + + } else { + // Clear ACPI Sleep Type + RESET_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x1c00 ); // 0x04 + } + + (*PeiServices)->SetBootMode(PeiServices, BootMode); +#else + (*PeiServices)->SetBootMode(PeiServices, BootMode); + // Clear ACPI Sleep Type + RESET_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x1c00 ); // 0x04 +#endif + } + } + } + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): End.\n")); + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegEndOfMrc +// +// Description: This function can be used to program any SB regisater at +// end of MRC. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegEndOfMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + IN EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + VOID *RecoveryModePpi; + + PEI_TRACE((-1,PeiServices, "ProgramSBRegEndOfMrc(): Start.\n")); + + Status = (*PeiServices)->LocatePpi (PeiServices, \ + &gRecoveryBootModeGuid, \ + 0, \ + NULL, \ + &RecoveryModePpi); + + if (EFI_ERROR(Status)) { + // Update Bootmode + (*PeiServices)->GetBootMode( PeiServices, &BootMode ); + PEI_TRACE((-1,PeiServices, "Before change BootMode = %X\n", BootMode)); + BootMode = BOOT_WITH_FULL_CONFIGURATION; + (*PeiServices)->SetBootMode(PeiServices, BootMode); + } + PEI_TRACE((-1,PeiServices, "ProgramSBRegEndOfMrc(): End.\n")); + + return EFI_SUCCESS; +} + +#if SB_RESET_PPI_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_ResetSystem +// +// Description: This function is the reset call interface function published +// by the reset PPI +// +// Input: PeiServices Pointer to the PEI services table +// +// Output: SYSTEM RESET +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBPEI_ResetSystem ( + IN EFI_PEI_SERVICES **PeiServices ) +{ +#if WdtPei_SUPPORT + WDT_PPI *Wdt; + EFI_STATUS Status; + + Status = (*PeiServices)->LocatePpi ( PeiServices, \ + &gWdtPpiGuid, \ + 0, \ + NULL, \ + &Wdt ); + + ASSERT_PEI_ERROR (PeiServices, Status); + + Wdt->AllowKnownReset(); +#endif + + SBLib_ResetSystem(EfiResetCold); + + // We should never get this far + return EFI_SUCCESS; +} + +#endif + +#if SB_STALL_PPI_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_Stall +// +// Description: This function provides a blocking stall at least number +// of microseconds by SB ACPI timer +// +// Input: PeiServices - Pointer to the PEI services table +// This - Pointer to the Stall PPI +// MicroSeconds - Number of microseconds for which to stall +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBPEI_Stall ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_STALL_PPI *This, + IN UINTN MicroSeconds ) +{ + EFI_STATUS Status; + EFI_PEI_PCI_CFG2_PPI *PciCfg; + + // Locate PciCfg PPI + PciCfg = (*PeiServices)->PciCfg; + + // At this time no manipulation needed. The value passed in is in + // MicroSeconds(us) and that is what the library function uses + + // Call Library function that is shared with Metronome + // Architecture Protocol + + + Status = CountTime(MicroSeconds, PM_BASE_ADDRESS); + + return Status; +} + +#endif + +#if ATAPI_RECOVERY_SUPPORT + +EFI_GUID gIdeRecoveryNativeModePpiGuid = \ + PEI_IDE_RECOVERY_NATIVE_MODE_PPI_GUID; + +PEI_IDE_RECOVERY_NATIVE_MODE_PPI IdeRecoveryNativeModePpi = { + SB_TEMP_IO_BASE+0x200, + SB_TEMP_IO_BASE+0x282, + SB_TEMP_IO_BASE+0x300, + SB_TEMP_IO_BASE+0x382 +}; + +EFI_PEI_PPI_DESCRIPTOR IdeRecoveryNativeModePpiDescriptor = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), \ + &gIdeRecoveryNativeModePpiGuid, &IdeRecoveryNativeModePpi +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSATARegs +// +// Description: This function initializes SATA controller registers +// for ATA/ATAPI recovery support. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSATARegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EnableAtaChannel +// +// Description: This function enables the specific channel of ATA/SATA +// controller(s) depend on input ChannelMask +// +// Input: PeiServices - Pointer to the PEI services table +// This - Pointer to the ATA Controller PPI +// ChannelMask - Mask for the specific channel. +// +// Output: EFI_STATUS +// +// Notes: Normally we have to enables all chennels on ATA/SATA +// controller(s) regardless of ChannelMask. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EnableAtaChannel ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ATA_CONTROLLER_PPI *This, + IN UINT8 ChannelMask ) +{ + EFI_STATUS Status; + + // SATA 0 (B0:D31:F2) + // Initialize the controller to IDE mode + RW_PCI8_SATA(R_PCH_SATA_MAP, 0, B_PCH_SATA_MAP_SMS_MASK | B_PCH_SATA_PORT_TO_CONTROLLER_CFG); // [EIP86096]>> + + //Enable the SATA2 for setting IDE mode to recovery + RESET_MEM32_RCRB (R_PCH_RCRB_FUNC_DIS ,BIT25); // <<[EIP86096] + + // Initialize Primary/Secondary IDE controller to operate in Legacy mode + RW_PCI8_SATA(R_PCH_SATA_PI_REGISTER, 0, B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE); + + // Enable IO space decode + RW_PCI16_SATA(R_PCH_SATA_COMMAND, B_PCH_SATA_COMMAND_IOSE, 0); + + if ((ChannelMask & PEI_ICH_IDE_PRIMARY) == PEI_ICH_IDE_PRIMARY) + // Enable Primary IDE Controller decode + RW_PCI16_SATA(R_PCH_SATA_TIMP, B_PCH_SATA_TIM_IDE, 0); + + if ((ChannelMask & PEI_ICH_IDE_SECONDARY) == PEI_ICH_IDE_SECONDARY) + // Enable Secondary IDE Controller decode + RW_PCI16_SATA(R_PCH_SATA_TIMS, B_PCH_SATA_TIM_IDE, 0); + + // Enable SATA ports 0, 1, 2 and 3. + RW_PCI16_SATA(R_PCH_SATA_PCS, (B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN | B_PCH_SATA_PCS_PORT3_EN), 0); + + // SATA 1 (B0:D31:F5) + RW_PCI16_SATA2(R_PCH_SATA_PCMD_BAR, SB_TEMP_IO_BASE + 0x200, 0); + RW_PCI16_SATA2(R_PCH_SATA_PCNL_BAR, SB_TEMP_IO_BASE + 0x282, 0); + RW_PCI16_SATA2(R_PCH_SATA_SCMD_BAR, SB_TEMP_IO_BASE + 0x300, 0); + RW_PCI16_SATA2(R_PCH_SATA_SCNL_BAR, SB_TEMP_IO_BASE + 0x382, 0); + + // Enable IO space decode + RW_PCI16_SATA2(R_PCH_SATA_COMMAND, B_PCH_SATA_COMMAND_IOSE, 0); + + if ((ChannelMask & PEI_ICH_IDE_PRIMARY) == PEI_ICH_IDE_PRIMARY) + // Enable Primary IDE Controller decode + RW_PCI16_SATA2(R_PCH_SATA_TIMP, B_PCH_SATA_TIM_IDE, 0); + + if ((ChannelMask & PEI_ICH_IDE_SECONDARY) == PEI_ICH_IDE_SECONDARY) + // Enable Secondary IDE Controller decode + RW_PCI16_SATA2(R_PCH_SATA_TIMS, B_PCH_SATA_TIM_IDE, 0); + + // Enable SATA1 ports 0(4) and 1(5). + RW_PCI16_SATA2(R_PCH_SATA_PCS, (B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN), 0); + + // Delay 1ms for HDD devices ready. + CountTime(1000, PM_BASE_ADDRESS); + + Status = (**PeiServices).InstallPpi( PeiServices, \ + &IdeRecoveryNativeModePpiDescriptor); + if (EFI_ERROR (Status)) return Status; + + return EFI_SUCCESS; +} +#endif // ATAPI_RECOVERY_SUPPORT + + + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* |