diff options
Diffstat (limited to 'ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/PcieComplex.c')
-rw-r--r-- | ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/PcieComplex.c | 1371 |
1 files changed, 1371 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/PcieComplex.c b/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/PcieComplex.c new file mode 100644 index 0000000..bf4b367 --- /dev/null +++ b/ReferenceCode/Chipset/SystemAgent/SaInit/Dxe/PcieComplex.c @@ -0,0 +1,1371 @@ +/** @file + This file will perform SA PCIE Root Complex initialization. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "SaBuildFlags.h" +#include "PciExpressInit.h" +#include "EdkIIGluePcdPciExpressLib.h" +#include "SaPcieLib.h" +#include "PcieComplex.h" +#include <Token.h> +/// +/// Global variables +/// +UINT8 HwStrap; +extern UINT16 mSaIotrapSmiAddress; +extern BOOLEAN mInitPcieAspmAfterOprom; +extern DXE_PLATFORM_SA_POLICY_PROTOCOL *mDxePlatformSaPolicy; + +#ifdef PEG_FLAG +PEG_PORT_DEVICE PegDeviceTable[] = { + /// + /// Bus, Device, Function, Slot, Bus2, Device2, Function2 + /// + { SA_PEG_BUS_NUM, SA_PEG10_DEV_NUM, SA_PEG10_FUN_NUM, 1, 2, 0, 0 } +// AMI_OVERRID >> +#if RC_PEG_1 == 1 + ,{ SA_PEG_BUS_NUM, SA_PEG11_DEV_NUM, SA_PEG11_FUN_NUM, 2, 3, 0, 0 } +#endif +#if RC_PEG_2 == 1 + ,{ SA_PEG_BUS_NUM, SA_PEG12_DEV_NUM, SA_PEG12_FUN_NUM, 3, 4, 0, 0 } +#endif +// AMI_OVERRID << +}; +#endif // PEG_FLAG + +/// +/// Functions +/// +VOID +EFIAPI +SaLateInitSmiCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/** + This function gets registered as a callback to perform all SA late initialization + + @param[in] Event - A pointer to the Event that triggered the callback. + @param[in] Context - A pointer to private data registered with the callback function. +**/ +{ + if (mSaIotrapSmiAddress != 0) { + DEBUG ((EFI_D_INFO, "[SA] Issue IOTRAP SMI %X\n", mSaIotrapSmiAddress)); + IoWrite8 (mSaIotrapSmiAddress, 0); + } + if (Event != NULL) { + gBS->CloseEvent(Event); + } + return; +} + +EFI_STATUS +Cid1EgressPort0Init ( + IN UINT64 EgressPortBar + ) +/** + Perform Egress Port 0 Initialization. + + @param[in] EgressPortBar - EPBAR Address + + @retval EFI_SUCCESS - Egress Port 0 initialization successed. +**/ +{ + UINT32 Data32And; + UINT32 Data32Or; + UINT8 Data8And; + UINT8 Data8Or; + UINT8 BitMask; + UINT8 BitValue; + + /// + /// Egress Port Configuration + /// + /// Egress Port Virtual Channel 0 Configuration + /// System BIOS must insure that only TC0 is mapped to VC0. + /// a. Set the Egress Port Register EPBAR offset 014h[7:1]=0000000b + /// + Data32And = BIT0; + Data32Or = 0; + Mmio32And (EgressPortBar, 0x14, Data32And); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x14), + &Data32Or, + &Data32And + ); + + /// + /// System BIOS must program the extended VC count field. + /// b. Set the Egress Port Register EPBAR offset 004h[2:0]=001b + /// + Data8And = (UINT8)~(0x07); + Data8Or = BIT0; + Mmio8AndThenOr (EgressPortBar, 0x4, Data8And, Data8Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (EgressPortBar + 0x4), + &Data8Or, + &Data8And + ); + + /// + /// Egress Port VC1 Configuration + /// a. Assign Virtual Channel ID 1 to VC1: by programming PXEPBAR Offset 020[26:24] = '001b' + /// b. Select and map TC1 to VC1: by programming PXPEPBAR Offset 020h[7:1] = '0000001b' + /// + Data32And = (UINT32)~(0x070000FE); + Data32Or = ((0x01 << 24) + BIT1); + Mmio32AndThenOr (EgressPortBar, 0x20, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x20), + &Data32Or, + &Data32And + ); + + /// + /// c. Enable VC1 (no hardware behind this bit, s/w compatibility flag only) BIT31 + /// Program EXPEPBAR Offset 020h[31]=1 + /// + Data32And = 0xFFFFFFFF; + Data32Or = BIT31; + Mmio32Or (EgressPortBar, 0x20, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x20), + &Data32Or, + &Data32And + ); + + /// + /// d. Poll the VC1 Negotiation Pending bit until it reads 0: + /// Read the Egress Port Register EPBAR Offset 026h until [1]==0 + /// + BitMask = (UINT8) BIT1; + BitValue = 0; + while ((Mmio8 (EgressPortBar, 0x26) & BitMask) != BitValue) { + }; + SCRIPT_MEM_POLL ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (EgressPortBar + 0x26), + &BitMask, + &BitValue, + 50, + 200000 + ); + + return EFI_SUCCESS; +} + +#ifdef PEG_FLAG +EFI_STATUS +Cid1PegPortInit ( + IN DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy + ) +/** + Conditionally perform PEG Port Initialization. + bugbug: organize this code in a way that can utilize the + PchS3ItemTypeInitPcieRootPortDownstream EFI_PCH_S3_DISPATCH_ITEM_TYPE + + @param[in] DxePlatformSaPolicy - SA DxePlatformPolicy protocol + + @retval EFI_SUCCESS - PEG Port initialization successed. +**/ +{ + UINT32 Data32; + UINT32 Data32Or; + UINT32 Data32And; + UINT16 Data16Or; + UINT16 Data16And; + UINT8 Data8; + UINT32 PegBaseAddress; + UINT8 Bus; + UINT8 Dev; + UINT8 Func; + UINT8 Slot; + UINT8 Bus2; + UINT8 Dev2; + UINT8 Func2; + UINT8 PegComplete; + CPU_FAMILY CpuFamilyId; + CPU_STEPPING CpuSteppingId; + + CpuFamilyId = GetCpuFamily(); + CpuSteppingId = GetCpuStepping(); + + /// + /// Read HwStrap Register - PEG1CFGSEL D1.R 504h [17:16] + /// + HwStrap = (UINT8) ((McD1PciCfg32 (R_SA_PEG_FUSESCMN_OFFSET) & (BIT17 + BIT16)) >> 16); + + /// + /// HSW - Scan/initialize PEG devices based on HW strapping. + /// + for (PegComplete = 0; PegComplete < ((sizeof (PegDeviceTable)) / (sizeof (PEG_PORT_DEVICE))); PegComplete++) { + /// + /// Get Peg Device BDF, Slot# and EndPoint(Temporary) + /// + Bus = PegDeviceTable[PegComplete].Bus; + Dev = PegDeviceTable[PegComplete].Device; + Func = PegDeviceTable[PegComplete].Function; + Slot = PegDeviceTable[PegComplete].Slot; + Bus2 = PegDeviceTable[PegComplete].Bus2; + Dev2 = PegDeviceTable[PegComplete].Device2; + Func2 = PegDeviceTable[PegComplete].Function2; + + PegBaseAddress = (UINT32) MmPciAddress (0, Bus, Dev, Func, 0); + /// + /// Check if the PEG is Enabled. Since Graphics initialization has already + /// occurred, simply check for PEG presence. + /// bugbug: need to make sure this dependency is captured in the integration guide + /// + if (McDevFunPciCfg16 (Bus, Dev, Func, PCI_VID) != 0xFFFF) { + /// + /// PEG port enable and visible + /// + /// + /// Initialize Slot Implemented for PCI Express Port + /// + Data16And = 0xFFFF; + Data16Or = BIT8; + + McDevFunPciCfg16Or (Bus, Dev, Func, R_SA_PEG_CAP_OFFSET, Data16Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PegBaseAddress + R_SA_PEG_CAP_OFFSET), + &Data16Or, + &Data16And + ); + + /// + /// Initialize "Physical Slot Number" for PCI Express Port + /// + Data32 = McDevFunPciCfg32 (Bus, Dev, Func, R_SA_PEG_SLOTCAP_OFFSET); + Data32 &= 0x0007FFFF; + /// + /// Set [31:19] - Slot # based on Peg Port + /// + Data32 |= (Slot << 19); + + /// + /// Initialize Slot Power Limit for PCI Express Port and Power Limit Scale. + /// Note: this register is a write once. + /// + /// Set [14:7] - 75 Watts (Default) + /// + Data32 &= 0xFFFE007F; + Data32 |= (75 << 7); + /// + /// [16:15] - 1.0 Watt Scale + /// + Data32 |= (0 << 15); + + McDevFunPciCfg32 (Bus, Dev, Func, R_SA_PEG_SLOTCAP_OFFSET) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_SLOTCAP_OFFSET), + 1, + &Data32 + ); + + /// + /// Additional Programming Steps + /// + /// Set PEG D.F.R 006h [15:0] = 0FFFFh + /// + Data32And = ~(0xFFFF0000); + Data32Or = 0xFFFF0000; + + McDevFunPciCfg32AndThenOr (Bus, Dev, Func, 0x4, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + 0x4), + &Data32Or, + &Data32And + ); + + /// + /// Set PEG D.F.R 01Eh [15:0] = 0FFFFh + /// + Data32And = ~(0xFFFF0000); + Data32Or = 0xFFFF0000; + + McDevFunPciCfg32AndThenOr (Bus, Dev, Func, 0x1C, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + 0x1C), + &Data32Or, + &Data32And + ); + + /// + /// Set PEG D.F.R 0AAh [15:0] = 0FFFFh + /// + Data32And = 0xFFFF; + Data32Or = 0xFFFF; + + McDevFunPciCfg16Or (Bus, Dev, Func, 0xAA, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PegBaseAddress + 0xAA), + &Data32Or, + &Data32And + ); + + /// + /// Set PEG D.F.R 1C4h [31:0] = 0FFFFFFFFh + /// + Data32 = 0xFFFFFFFF; + + McDevFunPciCfg32Or (Bus, Dev, Func, R_SA_PEG_PEGUESTS_OFFSET, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_PEGUESTS_OFFSET), + 1, + &Data32 + ); + + /// + /// Set PEG D.F.R 1D0h [31:0] = 0FFFFFFFFh + /// + Data32 = 0xFFFFFFFF; + + McDevFunPciCfg32Or (Bus, Dev, Func, R_SA_PEG_PEGCESTS_OFFSET, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_PEGCESTS_OFFSET), + 1, + &Data32 + ); + + /// + /// Set PEG D.F.R 1F0h [31:0] = 0FFFFFFFFh + /// + Data32 = 0xFFFFFFFF; + + McDevFunPciCfg32Or (Bus, Dev, Func, 0x1F0, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + 0x1F0), + 1, + &Data32 + ); + /// + /// If HSW CPU steppingId >= B0 or CRW, set BIT19 of DCAP2 register of the PEG port,to enable OBFF support using WAKE# signaling + /// + if (((CpuFamilyId == EnumCpuHsw) && (CpuSteppingId >= EnumHswB0)) || + (CpuFamilyId == EnumCpuCrw)) { + Data32 = (UINT32) BIT19; + McDevFunPciCfg32Or (Bus, Dev, Func, R_SA_PEG_DCAP2_OFFSET, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_DCAP2_OFFSET), + 1, + &Data32 + ); + } + /// + /// Complete Common Port and Endpoint Configuration + /// + /// + /// Virtual Channel Configuration of PCI Express Port + /// Set the VC0RCTL register D1:F0 Offset 114h [7:1] = 7Fh + /// + Data32And = 0xFFFFFF01; + Data32Or = BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1; + + McDevFunPciCfg32AndThenOr (Bus, Dev, Func, R_SA_PEG_VC0RCTL0_OFFSET, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_VC0RCTL0_OFFSET), + &Data32Or, + &Data32And + ); + /// + /// 6.8 Additional Programming Steps before Enabling ASPM for PEG device + /// + AdditionalPEGProgramStepsBeforeASPM (Bus, Dev, Func, DxePlatformSaPolicy); + + /// + /// 6.10 Interrupt Routing for PCI Express* + /// It is recommened to re-route the legacy interrupts (INTA -> INTB,C,D) + /// to avoid overcrowded INTA. ACPI PRT needs update. + /// The ACPI _PRT() methods for PEG controllers must match the legacy interrupt routing. + /// + if ((Dev == 1) && (Func == 1)) { + Data32And = (UINT32)~(BIT25 | BIT24); + Data32Or = BIT24 | BIT25; + McDevFunPciCfg32AndThenOr (Bus, Dev, Func, R_SA_PEG_CFG4_OFFSET, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_CFG4_OFFSET), + &Data32Or, + &Data32And + ); + } + + if ((Dev == 1) && (Func == 2)) { + Data32And = (UINT32)~(BIT25 | BIT24); + Data32Or = BIT25; + McDevFunPciCfg32AndThenOr (Bus, Dev, Func, R_SA_PEG_CFG4_OFFSET, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_CFG4_OFFSET), + &Data32Or, + &Data32And + ); + } + } + + /// + /// Lock offset 3Dh for Interrupt Pin + /// + Data8 = McDevFunPciCfg8 (Bus, Dev, Func, PCI_INTPIN); + McDevFunPciCfg8 (Bus, Dev, Func, PCI_INTPIN) = Data8; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (PegBaseAddress + PCI_INTPIN), + 1, + &Data8 + ); + + /// + /// Lock DCAP register + /// + Data32 = McDevFunPciCfg32 (Bus, Dev, Func, R_SA_PEG_DCAP_OFFSET); + McDevFunPciCfg32 (Bus, Dev, Func, R_SA_PEG_DCAP_OFFSET) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + R_SA_PEG_DCAP_OFFSET), + 1, + &Data32 + ); + + if ((CpuFamilyId == EnumCpuHsw) || (CpuFamilyId == EnumCpuCrw) + ){ + if ((Bus == 0) && (Dev == 1) && (Func == 0)) { + Data32 = McDevFunPciCfg32 (Bus, Dev, Func, 0xCD0); + Data32 |= BIT11; + McDevFunPciCfg32 (Bus, Dev, Func, 0xCD0) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PegBaseAddress + 0xCD0), + 1, + &Data32 + ); + } + } + + if ((HwStrap == SA_PEG_x16_x0_x0) && (PegComplete == 0)) { + break; + } + if ((HwStrap == SA_PEG_x8_x8_x0) && (PegComplete == 1)) { + break; + } + if ((HwStrap == SA_PEG_x8_x4_x4) && (PegComplete == 2)) { + break; + } + } + + return EFI_SUCCESS; +} +#endif // PEG_FLAG + +EFI_STATUS +Cid1Cid2DmiPortInit ( + IN UINT64 DmiBar, + IN DXE_PLATFORM_SA_POLICY_PROTOCOL *DxePlatformSaPolicy + ) +/** + DMI Port Initialization for both CID1 (Port 1 in MCH) and CID2 (Port 0 in PCH). + + @param[in] DmiBar - DMIBAR Address + @param[in] DxePlatformSaPolicy - SA DxePlatformPolicy protocol + + @retval EFI_SUCCESS - DMI Port initialization successed. +**/ +{ + UINT32 Data32Or; +#ifdef DMI_FLAG + UINT8 Data8And; + UINT8 Data8Or; + CPU_FAMILY CpuFamilyId; + + CpuFamilyId = GetCpuFamily(); +#endif // DMI_FLAG + +#ifdef DMI_FLAG + if ((CpuFamilyId == EnumCpuHsw) || (CpuFamilyId == EnumCpuCrw)) { + /// + /// Additional Programming Steps + /// + AdditionalDMIProgramStepsBeforeASPM (DmiBar, DxePlatformSaPolicy); + } +#endif // DMI_FLAG + + /// + /// Set DMIBAR Offset 1C4h [31:0] = 0FFFFFFFFh + /// + Data32Or = 0xFFFFFFFF; + Mmio32 (DmiBar, 0x1C4) = 0xFFFFFFFF; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x1C4), + 1, + &Data32Or + ); + + /// + /// Set DMIBAR Offset 1D0h [31:0] = 0FFFFFFFFh + /// + Data32Or = 0xFFFFFFFF; + Mmio32 (DmiBar, 0x1D0) = 0xFFFFFFFF; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x1D0), + 1, + &Data32Or + ); + +#ifdef DMI_FLAG + if ((CpuFamilyId == EnumCpuHsw) || (CpuFamilyId == EnumCpuCrw)) { + /// + /// Enable `Active State PM'. DMILCTL register at DMIBAR 088h [1:0] = '11b'. + /// Based on the policy: + /// + if (DxePlatformSaPolicy->PcieConfig->DmiAspm == PcieAspmAutoConfig || + DxePlatformSaPolicy->PcieConfig->DmiAspm == PcieAspmL0sL1 + ) { + /// + /// Enable ASPM = L0s and L1 Entry + /// + Data8And = 0xFC; + Data8Or = 0x03; + Mmio8Or (DmiBar, 0x88, Data8Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (DmiBar + 0x088), + &Data8Or, + &Data8And + ); + } else if (DxePlatformSaPolicy->PcieConfig->DmiAspm == PcieAspmL0s) { + /// + /// Enable ASPM = L0s + /// + Data8And = 0xFC; + Data8Or = 0x01; + Mmio8Or (DmiBar, 0x88, Data8Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (DmiBar + 0x088), + &Data8Or, + &Data8And + ); + } else if (DxePlatformSaPolicy->PcieConfig->DmiAspm == PcieAspmL1) { + /// + /// Enable ASPM = L1 + /// + Data8And = 0xFC; + Data8Or = 0x02; + Mmio8Or (DmiBar, 0x88, Data8Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (DmiBar + 0x088), + &Data8Or, + &Data8And + ); + } + + if (DxePlatformSaPolicy->PcieConfig->DmiExtSync == ENABLED) { + /// + /// Enable Extended Synch + /// + Data8And = 0xFF; + Data8Or = 0x10; + Mmio8Or (DmiBar, 0x88, Data8Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (DmiBar + 0x088), + &Data8Or, + &Data8And + ); + } + + if (DxePlatformSaPolicy->PcieConfig->DmiIot == ENABLED) { + /// + /// if DMI Iot is enabled, set DMIBAR offset 0xD34 = 0x44 + /// + Data8Or = 0x44; + Mmio8 (DmiBar, 0xD34) = 0x44; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (DmiBar + 0xD34), + 1, + (VOID *) (UINTN) (DmiBar + 0xD34) + ); + } + } +#endif // DMI_FLAG + + return EFI_SUCCESS; +} + +EFI_STATUS +Cid1TopologyInit ( + IN UINT64 EgressPortBar, + IN UINT64 DmiBar, + IN UINT32 PchRootComplexBar + ) +/** + Perform Root Complex Topology Initialization for CID1. + + @param[in] EgressPortBar - EPBAR Address + @param[in] DmiBar - DMIBAR Address + @param[in] PchRootComplexBar - PCH RCBA Address + + @retval EFI_SUCCESS - Root Complex topology initialization for CID1 successed. +**/ +{ + UINT32 Data32; + UINT32 Data32And; + UINT32 Data32Or; + UINT32 DwordReg; + UINT64 McD1Base; + UINT64 McD1F1Base; + UINT64 McD1F2Base; + + McD1Base = MmPciAddress (0, 0, 1, 0, 0); + McD1F1Base = MmPciAddress (0, 0, 1, 1, 0); + McD1F2Base = MmPciAddress (0, 0, 1, 2, 0); + + /// + /// Set the CID1 Egress Port 0 Topology + /// + /// + /// Step 1, Set the SA Component ID = 1. + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT16; + Mmio32AndThenOr (EgressPortBar, 0x44, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x44), + &Data32Or, + &Data32And + ); + + /// + /// Step 2, Set link 1 Target Component ID and valid (Bit 0 = 1b). + /// Set the Link 1 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + Mmio32AndThenOr (EgressPortBar, 0x50, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x50), + &Data32Or, + &Data32And + ); + + /// + /// Step 3, Set Link 1 to Reference the DMI RCRB (Bits 31:0 = DMI Base). + /// + Data32 = (UINT32) DmiBar; + MmioWrite32 ((UINTN) EgressPortBar + 0x58, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x58), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) EgressPortBar + 0x58 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x58 + 4), + 1, + &Data32 + ); + +#ifdef PEG_FLAG + /// + /// CID1 Egress port Root Topology and PciExpress Port (PEG Ports) Topology + /// Programming only if PEG devices are enabled. + /// + /// Step 1 PCI Express Enabled Check + /// Check and Configure CID1 root and Device 1 function 0 + /// + if (McD1PciCfg16 (PCI_VID) != 0xFFFF) { + /// + /// Step 4, Set Link 2 to Reference the Device 1 function 0. + /// + Data32 = (UINT32) 0x8000; + MmioWrite32 ((UINTN) EgressPortBar + 0x68, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x68), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) EgressPortBar + 0x68 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x68 + 4), + 1, + &Data32 + ); + + /// + /// Step 5, Set link 2 Target Component ID and valid bit(Offset 60h, Bit 0 = 1b) + /// Set the Link 2 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + Mmio32AndThenOr (EgressPortBar, 0x60, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x60), + &Data32Or, + &Data32And + ); + + /// + /// Set the CID1 PCI Express* Port Root Topology + /// + /// Step 2 Set the Link 1 CID = 1 144h(23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT16; + MmioAndThenOr32 ((UINTN) McD1Base + 0x144, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1Base + 0x144), + &Data32Or, + &Data32And + ); + + /// + /// Step 3. Set Link 1 to Reference the SA EP RCRB (Bits 31:0 = EPBAR). + /// + Data32 = (UINT32) EgressPortBar; + MmioWrite32 ((UINTN) McD1Base + 0x158, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1Base + 0x158), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) McD1Base + 0x158 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1Base + 0x158 + 4), + 1, + &Data32 + ); + + /// + /// Step 4 Set link 1 Target Component ID and valid bit(Offset 150h, Bit 0 = 1b) + /// Set the Link 1 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + MmioAndThenOr32 ((UINTN) McD1Base + 0x150, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1Base + 0x150), + &Data32Or, + &Data32And + ); + + /// + /// Step 5 Program Read-Only Write-Once Registers + /// D1.F0.R 0C4h [31:0] + /// + Data32And = 0xFFFFFFFF; + Data32Or = (UINT32) 0x00; + Data32 = McD1PciCfg32 (0xC4); + McD1PciCfg32 (0xC4) = Data32; + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1Base + 0xC4), + &Data32Or, + &Data32And + ); + } + /// + /// Check and Configure CID1 root and Device 1 function 1 + /// + if (McD1F1PciCfg16 (PCI_VID) != 0xFFFF) { + /// + /// Step 6, Set Link 3 to Reference the Device 1 function 1. + /// + Data32 = (UINT32) 0x9000; + MmioWrite32 ((UINTN) EgressPortBar + 0x78, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x78), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) EgressPortBar + 0x78 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x78 + 4), + 1, + &Data32 + ); + + /// + /// Step 7. Set the Link 3 Target Component ID and Valid Bit 70h [0] + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + Mmio32AndThenOr (EgressPortBar, 0x70, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x70), + &Data32Or, + &Data32And + ); + + /// + /// Step 2 Set the Link 1 CID = 1 144h(23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT16; + MmioAndThenOr32 ((UINTN) McD1F1Base + 0x144, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F1Base + 0x144), + &Data32Or, + &Data32And + ); + + /// + /// Step 3 Set Link 1 to Reference the IMC EP RCRB (Bits 31:0 = EPBAR). + /// + Data32 = (UINT32) EgressPortBar; + MmioWrite32 ((UINTN) McD1F1Base + 0x158, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F1Base + 0x158), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) McD1F1Base + 0x158 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F1Base + 0x158 + 4), + 1, + &Data32 + ); + + /// + /// Step 4 Set link 1 Target Component ID and valid bit(Offset 150h, Bit 0 = 1b) + /// Set the Link 1 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + MmioAndThenOr32 ((UINTN) McD1F1Base + 0x150, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F1Base + 0x150), + &Data32Or, + &Data32And + ); + + /// + /// Step 5 Program Read-Only Write-Once Registers + /// + Data32And = 0xFFFFFFFF; + Data32Or = (UINT32) 0x00; + Data32 = McD1F1PciCfg32 (0xC4); + McD1F1PciCfg32 (0xC4) = Data32; + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F1Base + 0xC4), + &Data32Or, + &Data32And + ); + } + /// + /// Check and Configure CID1 root and Device 1 function 2 + /// + if (McD1F2PciCfg16 (PCI_VID) != 0xFFFF) { + /// + /// Step 8, Set Link 4 to Reference the Device 1 function 2. + /// + Data32 = (UINT32) 0xA000; + MmioWrite32 ((UINTN) EgressPortBar + 0x88, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x88), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) EgressPortBar + 0x88 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x88 + 4), + 1, + &Data32 + ); + + /// + /// Step 9, Set the Link 4 Target Component ID and Valid Bit 80h [0] + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + Mmio32AndThenOr (EgressPortBar, 0x80, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (EgressPortBar + 0x80), + &Data32Or, + &Data32And + ); + + /// + /// Step 2. Set the Link 1 CID = 1 144h(23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT16; + MmioAndThenOr32 ((UINTN) McD1F2Base + 0x144, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F2Base + 0x144), + &Data32Or, + &Data32And + ); + + /// + /// Step 3. Set Link 1 to Reference the IMC EP RCRB (Bits 31:0 = EPBAR). + /// + Data32 = (UINT32) EgressPortBar; + MmioWrite32 ((UINTN) McD1F2Base + 0x158, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F2Base + 0x158), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) McD1F2Base + 0x158 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F2Base + 0x158 + 4), + 1, + &Data32 + ); + + /// + /// Step 4. Set link 1 Target Component ID and valid bit(Offset 150h, Bit 0 = 1b) + /// Set the Link 1 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + MmioAndThenOr32 ((UINTN) McD1F2Base + 0x150, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F2Base + 0x150), + &Data32Or, + &Data32And + ); + + /// + /// Step 5. Program Read-Only Write-Once Registers + /// + Data32And = 0xFFFFFFFF; + Data32Or = (UINT32) 0x00; + Data32 = McD1F2PciCfg32 (0xC4); + McD1F2PciCfg32 (0xC4) = Data32; + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (McD1F2Base + 0xC4), + &Data32Or, + &Data32And + ); + } +#endif // PEG_FLAG + + /// + /// Set the CID1 DMI Port Root Topology + /// + /// Step 1 Set the CID = 1 ( Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT16; + Mmio32AndThenOr (DmiBar, 0x44, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x44), + &Data32Or, + &Data32And + ); + + /// + /// Step 2. Set Link 1 Target Port Number = 0 (Bits 31:24 = 00h). + /// Step 3. Set Link 1 TCID = 2 (Bits 23:16 = 02h). + /// Step 4. Set Link 1 as valid (Bit 0 = 1b). + /// + Data32And = 0x0000FFFF; + Data32Or = (BIT17 + BIT0); + Mmio32AndThenOr (DmiBar, 0x50, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x50), + &Data32Or, + &Data32And + ); + + /// + /// Step 5, Set Link 1 to Reference the PCH RCRB + /// + Data32 = PchRootComplexBar; + Mmio32 (DmiBar, 0x58) = PchRootComplexBar; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x58), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + Mmio32 (DmiBar, 0x58 + 4) = Data32; + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x58 + 4), + 1, + &Data32 + ); + + /// + /// Step 6, Set Link 2 to Reference the IMC EP (Bits 31:0 = EP). + /// + Data32 = (UINT32) EgressPortBar; + MmioWrite32 ((UINTN) DmiBar + 0x68, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x68), + 1, + &Data32 + ); + Data32 = (UINT32) 0x00; + MmioWrite32 ((UINTN) DmiBar + 0x68 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x68 + 4), + 1, + &Data32 + ); + + /// + /// Step 7, Set link 2 Target Component ID and valid Bit(Bit 0 = 1b) + /// Set the Link 2 TCID = 1 (Bits 23:16 = 01h). + /// + Data32And = 0xFF00FFFF; + Data32Or = (BIT16 | BIT0); + Mmio32AndThenOr (DmiBar, 0x60, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (DmiBar + 0x60), + &Data32Or, + &Data32And + ); + + /// + /// Step 8. Program RO and Write-Once Registers + /// DMIBAR Offset 004h [31:0] + /// DMIBAR Offset 084h [31:0] + /// + DwordReg = Mmio32 (DmiBar, 0x4); + Mmio32 (DmiBar, 0x4) = DwordReg; + + DwordReg = Mmio32 (DmiBar, 0x84); + Mmio32 (DmiBar, 0x84) = DwordReg; + + return EFI_SUCCESS; +} + +EFI_STATUS +Cid2TopologyInit ( + IN UINT32 PchRootComplexBar, + IN UINT64 DmiBar + ) +/** + Perform Root Complex Topology Initialization for CID2. + Note: This sequence follows PCH BIOS specification Ver 0.5 section 8.3 + Root Complex Topology Programming + + @param[in] PchRootComplexBar - PCH RCBA Address + @param[in] DmiBar - DMIBAR Address + + @retval EFI_SUCCESS - Root Complex topology initialization for CID2 successed. +**/ +{ + UINT32 Data32; + UINT32 Data32And; + UINT32 Data32Or; + + /// + /// PCH BIOS specification Ver 0.5 section 8.3 Note 1,2 + /// program a value into this Component ID field to determine the Component ID of + /// ICH8, and this value must be different from the Component ID value of the MCH. + /// Set the CID = 2 (Offset 104h, Bits 23:16 = 02h). + /// + Data32And = 0xFF00FFFF; + Data32Or = BIT17; + MmioAndThenOr32 (PchRootComplexBar + 0x104, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PchRootComplexBar + 0x104), + &Data32Or, + &Data32And + ); + + /// + /// PCH BIOS specification Ver 0.5 section 8.3 Note 3,4 + /// Note 3: This Target Port # field must be filled in by System BIOS with the Port + /// # of the RCRB DMI link in the MCH. + /// Note 4: This Target CID field must be filled in by System BIOS with the + /// Component ID of the MCH. + /// Set the Link 1 Target Port Number = 1 (Offset 110h, bits 31:24 = 01h). + /// Set the Link 1 Target Component ID = 1 (Offset 110h, bits 23:16 = 01h). + /// + Data32And = 0x0000FFFF; + Data32Or = (BIT24 | BIT16); + MmioAndThenOr32 (PchRootComplexBar + 0x110, Data32And, Data32Or); + SCRIPT_MEM_READ_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PchRootComplexBar + 0x110), + &Data32Or, + &Data32And + ); + + /// + /// PCH BIOS specification Ver 0.5 section 8.3 Note 5 + /// Fill the Base Address field with the same base address of the RCRB DMI link in + /// the MCH, This register field is located at RCBA+ 0118h[63:0], + /// and will be locked once written until the next reset. + /// + Data32 = (UINT32) DmiBar; + MmioWrite32 (PchRootComplexBar + 0x118, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (PchRootComplexBar + 0x118), + 1, + &Data32 + ); + + Data32 = *((UINT32 *) (&DmiBar) + 1); + MmioWrite32 (PchRootComplexBar + 0x118 + 4, Data32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (PchRootComplexBar + 0x118 + 4), + 1, + &Data32 + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +PegInitBeforeExitPmAuth ( + VOID + ) +/** + This function performs Peg initialization before ExitPmAuth. + + @retval EFI_SUCCESS - Always. +**/ +{ +#if SA_PCIE_ASPM_IN_SMM == 1 + EFI_EVENT ReadyToBoot; + EFI_STATUS Status; +#endif + BOOLEAN AspmHasBeenHandled; + + DEBUG ((EFI_D_ERROR, "[SA] Pcie before ExitPmAuth callback.\n")); + AspmHasBeenHandled = FALSE; + /// + /// SMM mode ASPM handling + /// Check if supported and enabled + /// +#if SA_PCIE_ASPM_IN_SMM == 1 + if ((mInitPcieAspmAfterOprom == 1) && (mSaIotrapSmiAddress != 0)) { + /// + /// Do the Phase 1 SMI callback + /// This will enumerate PCIe downstream devices + /// + SaLateInitSmiCallback (NULL, NULL); + + /// + /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback + /// This will handle PEG ASPM programming after OROM execution + /// + Status = EfiCreateEventReadyToBootEx ( + EFI_TPL_NOTIFY, + SaLateInitSmiCallback, + NULL, + &ReadyToBoot + ); + ASSERT_EFI_ERROR (Status); + AspmHasBeenHandled = TRUE; + } +#endif + + /// + /// DXE mode ASPM handling + /// Check if SMM mode already taken care all things + /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization + /// +#if SA_PCIE_ASPM_IN_DXE == 1 + if (AspmHasBeenHandled == FALSE) { + /// + /// Initialize ASPM before OpROM, S3 Save script supported + /// First initialize all policy settings + /// Initialize module global variables - Stepping ID and Platform Policy + /// + SaPcieInitPolicy (mDxePlatformSaPolicy); + /// + /// Do initialization + /// + SaPcieEnumCallback (); + SaPcieConfigAfterOpRom (); + } +#endif + + return EFI_SUCCESS; +} + +EFI_STATUS +SaSecurityInit ( + VOID + ) +/** + This function performs SA Security locking in ExitPmAuth callback + + @retval EFI_SUCCESS - Security lock has done + @retval EFI_UNSUPPORTED - Security lock not done successfully +**/ +{ + BOOLEAN SecurityHasBeenHandled; + SecurityHasBeenHandled = FALSE; +#if SA_PCIE_ASPM_IN_SMM == 1 + if ((mInitPcieAspmAfterOprom == 1) && (mSaIotrapSmiAddress != 0)) { + /// + /// Generate the Phase 2 of SA SMI to do security lock + /// + SaLateInitSmiCallback (NULL, NULL); + + SecurityHasBeenHandled = TRUE; + } +#endif + + /// + /// Check if SMM mode already taken care this task + /// +#if SA_PCIE_ASPM_IN_DXE == 1 + if (SecurityHasBeenHandled == FALSE) { + SaSaveRestorePlatform (TRUE); + SaSecurityLock (); + SecurityHasBeenHandled = TRUE; + } +#endif + /// + /// Security locking is important so fail to do this will be an ERROR. + /// + if (SecurityHasBeenHandled == TRUE) { + return EFI_SUCCESS; + } else { + return EFI_UNSUPPORTED; + } +} |