summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c2469
1 files changed, 2469 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000..df7f05b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c
@@ -0,0 +1,2469 @@
+/** @file
+ This is the driver that initializes the Intel PCH.
+
+@copyright
+ Copyright (c) 1999 - 2015 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 "PchInit.h"
+#include "HeciMsgLib.h"
+#include "ChipsetInitHob.h"
+
+// [ EIP357393 ]+>>>
+#define AMI_PCI_BUS_EXT_PROTOCOL_GUID \
+{ 0xf42a009d, 0x977f, 0x4f08, 0x94, 0x40, 0xbc, 0xa5, 0xa3, 0xbe, 0xd9, 0xaf };
+
+static EFI_GUID gAmiExtPciBusProtocolGuid = AMI_PCI_BUS_EXT_PROTOCOL_GUID;
+// [ EIP357393 ]+<<<
+
+//
+// Global Variables
+//
+EFI_HANDLE mImageHandle;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+extern EFI_USB_HC_PORT_PRECONDITION *mPrivatePreConditionList;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+//
+// GUID Definitions
+//
+EFI_GUID gChipsetInitHobGuid = CHIPSET_INIT_INFO_HOB_GUID;
+EFI_GUID gEfiHeciProtocolGuid = HECI_PROTOCOL_GUID;
+
+//
+// EFI_EVENT
+//
+EFI_EVENT mHeciEvent;
+
+//
+// Local function prototypes
+//
+EFI_STATUS
+InitializePchDevice (
+ IN OUT PCH_INSTANCE_PRIVATE_DATA *PchInstance,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN UINT16 GpioBase
+ );
+
+EFI_STATUS
+ProgramSvidSid (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+VOID
+EFIAPI
+PchExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+VOID
+EFIAPI
+PchInitBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+// [ EIP357393 ]+>>>
+EFI_STATUS
+EFIAPI
+PchSpiLockBeforeEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+// [ EIP357393 ]+<<<
+
+EFI_STATUS
+ChipsetInitSettingsCheck (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+/**
+ Configures PCH IOBP and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+ProgramIobpWithScript (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ EFI_STATUS Status;
+
+ Status = ProgramIobp (RootComplexBar, Address, AndMask, OrMask);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ Address,
+ AndMask,
+ OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Configures 32-bit MMIO register and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+MmioAndThenOr32WithScript (
+ IN UINTN Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ MmioAndThenOr32 (Address, AndMask, OrMask);
+
+ PCH_INIT_COMMON_SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ Address,
+ &OrMask,
+ &AndMask
+ );
+}
+
+/**
+ This is the standard EFI driver point that detects
+ whether there is an PCH southbridge in the system
+ and if so, initializes the chip.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 BusNumber;
+ UINT32 RootComplexBar;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINT32 Index;
+ PCH_INSTANCE_PRIVATE_DATA *PchInstance;
+ UINT16 PmBase;
+ UINT16 GpioBase;
+ UINTN PciD31F0RegBase;
+
+ DEBUG ((EFI_D_INFO, "PchInitEntryPoint() Start\n"));
+
+ PchInstance = NULL;
+ PchPlatformPolicy = NULL;
+
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+ mImageHandle = ImageHandle;
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate and install the PCH Info protocol
+ ///
+ BusNumber = PchPlatformPolicy->BusNumber;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ RootComplexBar = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_RCBA) & B_PCH_LPC_RCBA_BAR;
+ PmBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ GpioBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR;
+
+ ASSERT (RootComplexBar != 0);
+ ASSERT (PmBase != 0);
+ ASSERT (GpioBase != 0);
+
+ DEBUG ((EFI_D_INFO, "PCH Device:\n-------------\n"));
+ DEBUG ((EFI_D_INFO, " RCBA 0x%X\n", RootComplexBar));
+ DEBUG ((EFI_D_INFO, " PmBase 0x%X\n", PmBase));
+ DEBUG ((EFI_D_INFO, " GpioBase 0x%X\n", GpioBase));
+ DEBUG ((EFI_D_INFO, "-------------\n"));
+
+ ///
+ /// Dump whole DXE_PCH_PLATFORM_POLICY_PROTOCOL and serial out.
+ ///
+ PchDumpPlatformProtocol (PchPlatformPolicy);
+ ///
+ /// Initialize the PCH device
+ ///
+ InitializePchDevice (PchInstance, PchPlatformPolicy, RootComplexBar, PmBase, GpioBase);
+
+ PchInstance = AllocateZeroPool (sizeof (PCH_INSTANCE_PRIVATE_DATA));
+ if (PchInstance == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PchInstance->PchInfo.Revision = PCH_INFO_PROTOCOL_REVISION_2;
+ PchInstance->PchInfo.BusNumber = BusNumber;
+ PchInstance->PchInfo.RCVersion = PCH_RC_VERSION;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ PchInstance->PchInfo.Preconditioned = mPrivatePreConditionList;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(HandleBuffer[Index]),
+ &gEfiPchInfoProtocolGuid,
+ &(PchInstance->PchInfo),
+ NULL
+ );
+ }
+
+ (gBS->FreePool) (HandleBuffer);
+
+ DEBUG ((EFI_D_INFO, "PchInitEntryPoint() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the PCH device according to the PCH Platform Policy protocol
+
+ @param[in, out] PchInstance PCH instance private data. May get updated by this function
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] PmBase Power Management IO base address of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+InitializePchDevice (
+ IN OUT PCH_INSTANCE_PRIVATE_DATA *PchInstance,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN AzaliaEnable;
+ UINT32 FuncDisableReg;
+ VOID *Registration;
+ VOID *Registration1; // [ EIP357393 ]
+ EFI_EVENT LegacyBootEvent;
+ EFI_EVENT ExitBootServicesEvent;
+ UINT16 LpcDeviceId;
+
+ DEBUG ((EFI_D_INFO, "InitializePchDevice() Start\n"));
+
+ FuncDisableReg = MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ ) + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// Take care of any ChipsetInit settings before going any further.
+ ///
+ Status = ChipsetInitSettingsCheck(PchPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Miscellaneous power management handling
+ ///
+ Status = ConfigureMiscPm (PchPlatformPolicy, RootComplexBar, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Additional power management setting
+ ///
+ Status = ConfigureAdditionalPm (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Configures PCH DMI power management configuration
+ ///
+ Status = ConfigureDmiPm (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Deep Sx Enabling
+ ///
+ Status = ProgramDeepSx (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Perform PCH initialization sequence
+ ///
+ Status = ConfigureMiscItems (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+#ifdef ADSP_FLAG
+ ///
+ /// Configure AudioDSP
+ ///
+ if(IS_PCH_LPTLP_LPC_DEVICE_ID(LpcDeviceId)) {
+ Status = ConfigureAudioDsp (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // ADSP_FLAG
+
+ ///
+ /// Detect and initialize the type of codec present in the system
+ ///
+ Status = ConfigureAzalia (PchPlatformPolicy, RootComplexBar, &AzaliaEnable);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Check to disable Azalia controller
+ ///
+ if (!AzaliaEnable) {
+ FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_AZALIA;
+ }
+ ///
+ /// Initialize LAN
+ ///
+ Status = ConfigureLan (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Configure USB
+ ///
+ Status = ConfigureUsb (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize PCIE root ports
+ ///
+ Status = PchInitRootPorts (PchPlatformPolicy, RootComplexBar, PmBase, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Thermal controller already enabled in PEI
+ ///
+
+ ///
+ /// Sata Controllers
+ ///
+ Status = ConfigureSata (PchPlatformPolicy, RootComplexBar, &FuncDisableReg, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Display link
+ ///
+ Status = ConfigureDisplay (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Set the PCH Function Disable Register
+ ///
+ MmioWrite32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS), (UINT32) (FuncDisableReg));
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ 1,
+ &FuncDisableReg
+ );
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &FuncDisableReg, // BitMask
+ &FuncDisableReg, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ ///
+ /// Perform clock gating register settings
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10 Enabling Clock Gating
+ ///
+ Status = ConfigureClockGating (PchPlatformPolicy, RootComplexBar, FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = ConfigureIoApic (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = ProgramSvidSid (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+#ifdef SERIAL_IO_FLAG
+ ///
+ /// Configure Serial IO Controllers
+ ///
+ if(IS_PCH_LPTLP_LPC_DEVICE_ID(LpcDeviceId)) {
+ Status = ConfigureSerialIo (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // SERIAL_IO_FLAG
+
+// [ EIP357393 ]+>>>
+ // Create an AMI ExtPciBus protocol call back event.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gAmiExtPciBusProtocolGuid,
+ EFI_TPL_CALLBACK,
+ PchSpiLockBeforeEndOfDxe,
+ NULL,
+ &Registration1
+ );
+// [ EIP357393 ]+<<<
+
+ ///
+ /// Create an ExitPmAuth protocol call back event.
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gExitPmAuthProtocolGuid,
+ EFI_TPL_CALLBACK,
+ PchInitBeforeBoot,
+ NULL,
+ &Registration
+ );
+
+ ///
+ /// Create events for PCH to do the task before ExitBootServices/LegacyBoot.
+ /// It is guaranteed that only one of two events below will be signalled
+ ///
+ Status = gBS->CreateEvent (
+ EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_CALLBACK,
+ PchExitBootServicesEvent,
+ NULL,
+ &ExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EfiCreateEventLegacyBootEx (
+ EFI_TPL_CALLBACK,
+ PchExitBootServicesEvent,
+ NULL,
+ &LegacyBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchDevice() End\n"));
+
+ return Status;
+}
+
+/**
+ Program Pch devices Subsystem Vendor Identifier (SVID) and Subsystem Identifier (SID).
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ProgramSvidSid (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 Index;
+ UINT16 EhciAccessCntl;
+ UINT8 BusNumber;
+ UINTN PciEAddressBase;
+ UINT8 DeviceNumber;
+ UINT8 FunctionNumber;
+ UINT8 SvidRegOffset;
+ BOOLEAN IsPchEhci;
+ STATIC PCH_SVID_SID_INIT_ENTRY SvidSidInitTable[] = {
+ {
+ 31,
+ 0,
+ R_PCH_LPC_SS
+ },
+ {
+ 31,
+ 2,
+ R_PCH_SATA_AHCI_SVID
+ },
+ {
+ 31,
+ 5,
+ R_PCH_SATA_AHCI_SVID
+ },
+ {
+ 31,
+ 3,
+ R_PCH_SMBUS_SVID
+ },
+ {
+ 31,
+ 6,
+ R_PCH_THERMAL_SVID
+ },
+ {
+ 29,
+ 0,
+ R_PCH_EHCI_SVID
+ },
+ {
+ 26,
+ 0,
+ R_PCH_EHCI_SVID
+ },
+ {
+ 20,
+ 0,
+ R_PCH_XHCI_SVID
+ },
+ {
+ 27,
+ 0,
+ R_PCH_HDA_SVID
+ },
+ {
+ 28,
+ 0,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 1,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 2,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 3,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 4,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 5,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 6,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 7,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 25,
+ 0,
+ R_PCH_LAN_SVID
+ },
+ /* HECI */
+ {
+ 22,
+ 0,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 1,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 2,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 3,
+ PCI_SVID_OFFSET
+ }
+ };
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ProgramSvidSid() Start\n"));
+
+ PchSeries = GetPchSeries();
+ EhciAccessCntl = 0;
+ BusNumber = PchPlatformPolicy->BusNumber;
+
+ if ((PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId != 0) ||
+ (PchPlatformPolicy->DefaultSvidSid->SubSystemId != 0)) {
+ for (Index = 0; Index < (sizeof (SvidSidInitTable) / sizeof (PCH_SVID_SID_INIT_ENTRY)); Index++) {
+ DeviceNumber = SvidSidInitTable[Index].DeviceNumber;
+ FunctionNumber = SvidSidInitTable[Index].FunctionNumber;
+ SvidRegOffset = SvidSidInitTable[Index].SvidRegOffset;
+ PciEAddressBase = MmPciAddress (
+ 0,
+ BusNumber,
+ DeviceNumber,
+ FunctionNumber,
+ 0
+ );
+ ///
+ /// Skip if the device is disabled
+ ///
+ if (MmioRead16 (PciEAddressBase) != V_PCH_INTEL_VENDOR_ID) {
+ continue;
+ }
+
+ IsPchEhci = FALSE;
+ if (PchSeries == PchH) {
+ IsPchEhci = IS_PCH_H_EHCI (DeviceNumber, FunctionNumber);
+ } else if (PchSeries == PchLp) {
+ IsPchEhci = IS_PCH_LP_EHCI (DeviceNumber, FunctionNumber);
+ }
+
+ ///
+ /// Set EHCI devices WRT_RDONLY bit (D29:F0,D26:F0:80h, bit 0) to 1, to make SVID and SID registers are writable
+ ///
+ if (IsPchEhci) {
+ EhciAccessCntl = MmioRead16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL));
+ MmioOr16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL), B_PCH_EHCI_ACCESS_CNTL_ENABLE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL)
+ );
+ }
+
+ if ((DeviceNumber == 22 && FunctionNumber == 2) || (DeviceNumber == 22 && FunctionNumber == 3)) {
+ ///
+ /// Sub System Identifiers register of D22:F2&F3 is 32bit access and write once
+ ///
+ MmioWrite32 (
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ (UINT32) (PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId |
+ (PchPlatformPolicy->DefaultSvidSid->SubSystemId << 16))
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + SvidRegOffset)
+ );
+ } else {
+ ///
+ /// Program Pch devices Subsystem Vendor Identifier (SVID)
+ ///
+ MmioWrite16 (
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + SvidRegOffset)
+ );
+
+ ///
+ /// Program Pch devices Subsystem Identifier (SID)
+ ///
+ MmioWrite16 (
+ (UINTN) (PciEAddressBase + SvidRegOffset + 2),
+ PchPlatformPolicy->DefaultSvidSid->SubSystemId
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + SvidRegOffset + 2),
+ 1,
+ (VOID *) (PciEAddressBase + SvidRegOffset + 2)
+ );
+ }
+ ///
+ /// Restore the EHCI devices WRT_RDONLY bit (D29:F0,D26:F0:80h, bit 0) value
+ ///
+ if (IsPchEhci) {
+ MmioWrite16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL), EhciAccessCntl);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ &EhciAccessCntl
+ );
+ }
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ProgramSvidSid() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize R/WO Registers that described in PCH BIOS Spec
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PciERWORegInit (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINTN Index;
+ UINTN PciD31F5RegBase;
+ UINT8 BusNumber;
+ UINT8 RootPortFunction;
+ UINTN RPBase;
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT8 Data8;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "PciERWORegInit() Start\n"));
+
+ PchSeries = GetPchSeries();
+ BusNumber = PchPlatformPolicy->BusNumber;
+ PciD31F5RegBase = 0;
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, BusNumber, 31, 5, 0);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.12 R/WO Registers, Table 5-4
+ /// System BIOS must read the register and write the same value back to the register
+ /// before passing control to the operating system.
+ /// Dev:Func/Type Register Offset Register Name Bits
+ /// D28:F0-F7 034h Capabilities Pointer 7:0
+ /// D28:F0-F7 040h Capabilities List 15:8
+ /// D28:F0-F7 042h PCI Express Capabilities 8
+ /// D28:F0~F7 044h Device Capabilities 2:0
+ /// D28:F0-F7 04Ch Link Capabilities 11:10, 17:15
+ /// D28:F0-F7 050h Link Control 3
+ /// D28:F0-F7 054h Slot Capabilities 31:19, 16:5
+ /// D28:F0-F7 064h Device Capabilities 2 11
+ /// D28:F0-F7 080h Message Signaled Interrupt Capability ID 15:8
+ /// D28:F0-F7 090h Port Mapping Regster 15:8
+ /// D28:F0-F7 094h Subsystem Vendor ID 31:0
+ /// D28:F0-F7 0D8h Miscellaneous Port Configuration 23, 2
+ /// D28:F0-F7 404h Latency Tolerance Reporting Override 2 2
+ /// RCBA 21A4h Link Capabilities 17:15 For PCH H
+ /// D31:F5 0A8h Next Capabilities Pointer 15:8
+ /// D31:F5 0B2h Capabilities List 9:8
+ ///
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ if (((*FuncDisableReg) & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << Index)) == 0) {
+ RootPortFunction = GetPchPcieRpfn(RootComplexBar, (UINT8)Index);
+ RPBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, RootPortFunction, 0);
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_LCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_LCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_LCAP),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_SVID);
+ MmioWrite32 (RPBase + R_PCH_PCIE_SVID, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_SVID),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_SLCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_SLCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_SLCAP),
+ 1,
+ &Data32
+ );
+ ///
+ /// Added PCIe register to be lockdown
+ ///
+ Data8 = MmioRead8 (RPBase + R_PCH_PCIE_CAPP);
+ MmioWrite8 (RPBase + R_PCH_PCIE_CAPP, Data8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_CAPP),
+ 1,
+ &Data8
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_CLIST);
+ MmioWrite16 (RPBase + R_PCH_PCIE_CLIST, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_CLIST),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_DCAP);
+ MmioWrite16 (RPBase + R_PCH_PCIE_DCAP, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_DCAP),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_MID);
+ MmioWrite16 (RPBase + R_PCH_PCIE_MID, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_MID),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_SVCAP);
+ MmioWrite16 (RPBase + R_PCH_PCIE_SVCAP, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_SVCAP),
+ 1,
+ &Data16
+ );
+
+ if (PchSeries == PchLp) {
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_L1SECH);
+ Data32 |= V_PCH_PCIE_L1SECH_L1SUBST_CAP_ID;
+ MmioWrite32 (RPBase + R_PCH_PCIE_L1SECH, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_L1SECH),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_L1SCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_L1SCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_L1SCAP),
+ 1,
+ &Data32
+ );
+ }
+ }
+ }
+
+ if (PchSeries == PchH) {
+ ///
+ /// D31:F5:A8h[15:8]
+ ///
+ Data16 = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_CR0);
+ MmioWrite16 (PciD31F5RegBase + R_PCH_SATA_CR0, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_CR0),
+ 1,
+ &Data16
+ );
+ ///
+ /// D31:F5:B2h[9:8]
+ ///
+ Data16 = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_FLR_CLV);
+ MmioWrite16 (PciD31F5RegBase + R_PCH_SATA_FLR_CLV, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_FLR_CLV),
+ 1,
+ &Data16
+ );
+ }
+
+ ///
+ /// D28:F0-F7:42h[8] (PCI Express Capabilities) has been done in PchInitRootPorts().
+ /// D28:F0-F7:4Ch[17:15] (Link Capabilities) has been done in PchInitSingleRootPort().
+ /// D28:F0-F7:404h[2] (Latency Tolerance Reporting Override 2) has been done in PchInitSingleRootPort().
+ /// RCBA + 21A4h[17:15] (Link Capabilities) has been done in ConfigureDmiPm() for PCH H.
+ ///
+
+ DEBUG ((EFI_D_INFO, "PciERWORegInit() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set a Root Port Downstream devices ASPM and LTR S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] RootPortAspm Root port Aspm configuration
+ @param[in] NumOfDevAspmOverride Number of Device specific ASPM policy override items
+ @param[in] DevAspmOverride Pointer to array of Device specific ASPM policy override items
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[in] NumOfDevLtrOverride Number of Device specific LTR override items
+ @param[in] DevLtrOverride Pointer to array of Device specific LTR policy override items
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SetPciePmS3Item (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspm,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN BOOLEAN FirstRPToSetPm,
+ IN BOOLEAN L1SupportedInAllEnabledPorts,
+ IN BOOLEAN ClkreqSupportedInAllEnabledPorts
+ )
+{
+ EFI_STATUS Status;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+ STATIC EFI_PCH_S3_PARAMETER_PCIE_SET_PM S3ParameterSetPm;
+ STATIC EFI_PCH_S3_DISPATCH_ITEM S3DispatchItem = {
+ PchS3ItemTypePcieSetPm,
+ &S3ParameterSetPm
+ };
+ EFI_PHYSICAL_ADDRESS S3DispatchEntryPoint;
+
+ if (!PchS3Support) {
+ DEBUG ((EFI_D_INFO, "Locating the S3 Support Protocol - PCH Init\n"));
+
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Located the S3 Support Protocol - PCH Init: %x\n", (UINTN)PchS3Support));
+ }
+
+ DEBUG ((EFI_D_INFO, "Attempting to set Custom PCH Init Dispatch Item\n"));
+
+ S3ParameterSetPm.RootPortBus = RootPortBus;
+ S3ParameterSetPm.RootPortDevice = RootPortDevice;
+ S3ParameterSetPm.RootPortFunc = RootPortFunc;
+ S3ParameterSetPm.RootPortAspm = RootPortAspm;
+ S3ParameterSetPm.NumOfDevAspmOverride = NumOfDevAspmOverride;
+ S3ParameterSetPm.DevAspmOverrideAddr = (UINT32) (UINTN) DevAspmOverride;
+ S3ParameterSetPm.TempBusNumberMin = TempBusNumberMin;
+ S3ParameterSetPm.TempBusNumberMax = TempBusNumberMax;
+ S3ParameterSetPm.PchPwrOptPcie = (UINT32) (UINTN) PchPwrOptPcie;
+ S3ParameterSetPm.NumOfDevLtrOverride = NumOfDevLtrOverride;
+ S3ParameterSetPm.DevLtrOverrideAddr = (UINT32) (UINTN) DevLtrOverride;
+ S3ParameterSetPm.L1SubstatesConfig = L1SubstatesConfig;
+ S3ParameterSetPm.PolicyRevision = PolicyRevision;
+ S3ParameterSetPm.FirstRPToSetPm = FirstRPToSetPm;
+ S3ParameterSetPm.L1SupportedInAllEnabledPorts = L1SupportedInAllEnabledPorts;
+ S3ParameterSetPm.ClkreqSupportedInAllEnabledPorts = ClkreqSupportedInAllEnabledPorts;
+ Status = PchS3Support->SetDispatchItem (
+ PchS3Support,
+ &S3DispatchItem,
+ &S3DispatchEntryPoint
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Save the script dispatch item in the Boot Script
+ ///
+ SCRIPT_DISPATCH (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, S3DispatchEntryPoint);
+#else
+ Status = EFI_SUCCESS;
+#endif
+ return Status;
+}
+
+/**
+ PCH initialization before ExitBootServices / LegacyBoot events
+ Useful for operations which must happen later than at EndOfPost event
+
+ @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.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINTN Index;
+ UINT32 AhciBar;
+ UINTN PciD31F2RegBase;
+ UINT16 SataModeSelect;
+ UINT16 LpcDeviceId;
+ UINT32 PxSctlDet;
+ UINT32 PxCmdSud;
+ UINT16 OrgCmdWord;
+
+ ///
+ /// Closed the event to avoid call twice
+ ///
+ gBS->CloseEvent (Event);
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ ) + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return;
+ }
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return;
+ }
+
+ ConfigureXhciAtBoot (PchPlatformPolicy);
+#ifdef SERIAL_IO_FLAG
+ ConfigureSerialIoAtBoot(PchPlatformPolicy);
+#endif // SERIAL_IO_FLAG
+
+ ///
+ /// eSATA port support only up to Gen2
+ ///
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, 0);
+ //
+ // Make sure SATA device exists.
+ //
+ if (MmioRead16 (PciD31F2RegBase + R_PCH_SATA_VENDOR_ID) != 0xFFFF) {
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ if ((SataModeSelect == V_PCH_SATA_MAP_SMS_AHCI) ||
+ (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID)) {
+ AhciBar = MmioRead32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR) & B_PCH_SATA_AHCI_BAR_BA;
+ //
+ // Make sure the AhciBar is valid.
+ //
+ if ((AhciBar != 0x00000000) && (AhciBar != 0xFFFFFFFF)) {
+ ///
+ /// Keep original CMD word, and enable MSE
+ ///
+ OrgCmdWord = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_COMMAND);
+ if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) {
+ MmioOr16 ((PciD31F2RegBase + R_PCH_SATA_COMMAND), B_PCH_SATA_COMMAND_MSE);
+ }
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if (PchPlatformPolicy->SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ PxSctlDet = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))) & B_PCH_SATA_AHCI_PXSCTL_DET;
+ PxCmdSud = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))) & B_PCH_SATA_AHCI_PxCMD_SUD;
+ ///
+ /// Limit speed to Gen2
+ ///
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD),
+ (UINT32) V_PCH_SATA_AHCI_PXSCTL_SPD_2
+ );
+ ///
+ /// If port is not offline, and it's spin up, need to port reset.
+ /// After port reset, clear the SERR.
+ /// - Set DET=1, and then set DET=0.
+ ///
+ if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_0) &&
+ (PxCmdSud == B_PCH_SATA_AHCI_PxCMD_SUD))
+ {
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_1);
+ PchPmTimerStall (1000);
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET));
+ MmioWrite32 (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index)), (UINT32)~0u);
+ }
+ ///
+ /// If port is offline, and it's not spin up, meets the power bug.
+ /// Need to do the W/A to spin up the port and then spin down.
+ /// Then entering back to offline and listen.
+ /// - Set DET=0, SUD=1, and then set SUD=0, DET=4.
+ ///
+ if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_4) &&
+ (PxCmdSud == 0))
+ {
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET));
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_SUD);
+ PchPmTimerStall (1000);
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD));
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_4);
+ }
+ }
+ }
+ ///
+ /// Restore original CMD word.
+ ///
+ if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) {
+ MmioWrite16 ((PciD31F2RegBase + R_PCH_SATA_COMMAND), OrgCmdWord);
+ }
+ } // AhciBar is vaild
+ } // SATA mode is AHCI or RAID
+ } // if D31F2 is existed
+ }
+
+ return;
+}
+
+/**
+ PCH checkes the HECI protocol and sends ChipsetInitSyncMsg
+
+ @param[in] Event Event objext
+ @param[in] *Context VOID Pointer
+
+ @retval None
+**/
+VOID
+EFIAPI
+ChipsetInitSyncCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ CHIPSET_INIT_INFO_HOB *ChipsetInitHob;
+
+ ChipsetInitHob = NULL;
+ Status = EFI_SUCCESS;
+ DEBUG ((EFI_D_INFO, "ChipsetInitSyncCallback() Start\n"));
+
+ //
+ // Get the HECI protocol to make sure HECI is ready.
+ //
+ Status = gBS->LocateProtocol (&gEfiHeciProtocolGuid, NULL, (VOID **) &Heci);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ if (mHeciEvent) {
+ gBS->CloseEvent (mHeciEvent);
+ }
+
+ //
+ // Search for the ChipsetInit Info PEIM GUID HOB.
+ //
+ ChipsetInitHob = GetFirstGuidHob (&gChipsetInitHobGuid);
+ if (ChipsetInitHob == NULL) {
+ DEBUG ((EFI_D_INFO, "ChipsetInitHob not found.\n"));
+ return;
+ }
+
+ //
+ // If ChipsetInitTableUpdReq == 0, settings are already in sync and no furhter work needed
+ //
+ if (ChipsetInitHob->ChipsetInitTableUpdReq == 1) {
+ //
+ // If we do not have the ChipsetInit table that ME FW expects us to have,
+ // we must send the current ChipsetInit table to ME FW via HECI message.
+ //
+ Status = HeciChipsetInitSyncMsg(ChipsetInitHob->ChipsetInitTable, ChipsetInitHob->ChipsetInitTableLen);
+ }
+
+ DEBUG ((EFI_D_INFO, "ChipsetInitSyncCallback() End\n"));
+
+ return;
+}
+
+/**
+ Register the HECI protocol callback function for the ChipsetInit sync message.
+
+ @param[in] *PchPlatformPolicy A pointer to the PchPlatformPolicy.
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+ChipsetInitSettingsCheck (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+ EFI_STATUS Status;
+ VOID *HeciRegistration;
+
+ DEBUG ((EFI_D_INFO, "ChipsetInitSettingsCheck() Start\n"));
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ ChipsetInitSyncCallback,
+ NULL,
+ &mHeciEvent
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiHeciProtocolGuid,
+ mHeciEvent,
+ &HeciRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ ChipsetInitSyncCallback (NULL, NULL);
+
+ return Status;
+}
+
+/**
+ Update ASL object before Boot
+
+ @param[in] *PchPlatformPolicy A pointer to the PchPlatformPolicy.
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_STATUS
+ @retval EFI_NOT_READY The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateAslObjects (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN VariableSize;
+ UINT32 PciMemBase;
+ PCH_LATE_INIT_SMM_VARIABLE SaveRestoreData;
+ UINT32 AslSignature;
+ UINT32 RpFn;
+ UINT32 Data32;
+
+ Status = InitializePchAslUpdateLib();
+ DEBUG ((EFI_D_INFO, "InitializePchAslUpdateLib Status %x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Update SRMB, Save & Restore Memroy Base
+ //
+ VariableSize = sizeof (PCH_LATE_INIT_SMM_VARIABLE);
+ Status = gRT->GetVariable (
+ PCH_INIT_PEI_VARIABLE_NAME,
+ &gPchInitPeiVariableGuid,
+ NULL,
+ &VariableSize,
+ &SaveRestoreData
+ );
+ PciMemBase = SaveRestoreData.PciMemBase;
+ Status = UpdateNameAslCode(EFI_SIGNATURE_32('S','R','M','B'), &PciMemBase, sizeof(PciMemBase));
+
+ RpFn = MmioRead32 (RootComplexBar + R_PCH_RCRB_RPFN);
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ //
+ // Update RPA0, RPA1, RPA2, RPA3, RPA4, RPA5, RPA6, RPA7 for root port function swapping
+ //
+ Data32 = '0' + (UINT32)Index;
+ AslSignature = EFI_SIGNATURE_32('R','P','A',Data32);
+ Data32 = (UINT32)((RpFn >> (Index * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+ Data32 |= (UINT32)(PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16);
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update RPAx %x %x\n", Index, Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE
+ //
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ AslSignature = EFI_SIGNATURE_32('P','M','L',(UINT32)('1' + Index));
+ Data32 = (UINT32) PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[Index].LtrMaxSnoopLatency;
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update PMLx %x %x\n", Index+1, Data32));
+ ASSERT_EFI_ERROR (Status);
+ AslSignature = EFI_SIGNATURE_32('P','N','L',(UINT32)('1' + Index));
+ Data32 = (UINT32) PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[Index].LtrMaxNoSnoopLatency;
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update PNLx %x %x\n", Index+1, Data32));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ //
+ // Update PCHS.
+ //
+ Data32 = (UINT32) GetPchSeries();
+ Status = UpdateNameAslCode(EFI_SIGNATURE_32('P','C','H','S'), &Data32, sizeof(UINT32));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ PCH initialization before Boot Sript Table is closed
+
+ @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.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchInitBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINT32 RootComplexBar;
+ UINT32 FuncDisableReg;
+ UINTN PciD25F0RegBase;
+ UINTN PciD31F2RegBase;
+ UINT32 GbEMemBar;
+ UINTN PciD31F0RegBase;
+ UINTN GbeRootPortNumber;
+ UINT16 PmBase;
+ UINT16 GpioBase;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 Data32;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT8 Data8;
+ VOID *ProtocolPointer;
+ UINTN AzaliaBase;
+ const UINT8 StrEnabled[sizeof (PCH_CRID_ENABLED)] = PCH_CRID_ENABLED;
+ const UINT8 StrDisabled[sizeof (PCH_CRID_DISABLED)] = PCH_CRID_DISABLED;
+ EFI_HANDLE Handle;
+ PCH_SERIES PchSeries;
+ BOOLEAN L1SubstatesSupportedPerPort;
+ PCI_DATA_STRUCTURE *PcirBlockPtr;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_EXPANSION_ROM_HEADER *RomImage;
+ BOOLEAN FoundLegacyRaid;
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
+ CHAR16 RstDriverName1[] = L"Intel RST";
+ CHAR16 RstDriverName2[] = L"Intel(R) RST";
+ EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
+ EFI_STRING DriverName;
+ UINT16 AspmVal;
+ BOOLEAN ClkreqPerPortSupported;
+ BOOLEAN ClkreqSupportedInAllEnabledPorts;
+ BOOLEAN L1SupportedInAllEnabledPorts;
+ BOOLEAN FirstRPToSetPm;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+#endif
+
+ UINTN RPBase;
+ UINT8 PortIndex;
+ PCH_PCIE_DEVICE_ASPM_OVERRIDE *S3DevAspmOverrideTbl;
+ PCH_PCIE_PWR_OPT *S3PchPwrOptPcie;
+ UINT32 DevAspmOverrideTblSize;
+ PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspmVal;
+ UINT8 NumOfDevltrOverride;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *S3DevLtrOverrideTbl;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverrideTbl;
+ UINT32 DevLtrOverrideTblSize;
+ PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubVal;
+ BOOLEAN LtrSupported;
+
+ S3DevLtrOverrideTbl = NULL;
+ DevLtrOverrideTbl = NULL;
+ NumOfDevltrOverride = 0;
+ LtrSupported = TRUE;
+ L1SubstatesSupportedPerPort = FALSE;
+ Handle = NULL;
+ PchSeries = GetPchSeries();
+ AspmVal = 0;
+ ClkreqPerPortSupported = FALSE;
+ ClkreqSupportedInAllEnabledPorts = TRUE;
+ L1SupportedInAllEnabledPorts = TRUE;
+ FirstRPToSetPm = TRUE;
+
+ ///
+ /// Check whether this is real ExitPmAuth notification, or just a SignalEvent
+ ///
+ Status = gBS->LocateProtocol (&gExitPmAuthProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ DEBUG ((EFI_D_INFO, "PchInitBeforeBoot() Start\n"));
+
+ ///
+ /// Closed the event to avoid call twice when launch shell
+ ///
+ gBS->CloseEvent (Event);
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return;
+ }
+ ///
+ /// Find the matching PCH Policy protocol
+ ///
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return;
+ }
+
+ InitFviDataHubCbContext (
+ PchPlatformPolicy->MiscConfig->FviSmbiosType,
+ (UINT8) mPchFviElements,
+ &mPchFviVersionData
+ );
+
+ RootComplexBar = PCH_RCRB_BASE;
+
+ FuncDisableReg = MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ GpioBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR;
+ PmBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ Status = PciERWORegInit (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locking Thermal Reporting Settings prior to end of POST
+ ///
+ Status = ThermalLockDown (PchPlatformPolicy, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+
+ if ((FuncDisableReg & B_PCH_RCRB_FUNC_DIS_AZALIA) == 0) {
+ AzaliaBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_AZALIA,
+ PCI_FUNCTION_NUMBER_PCH_AZALIA,
+ 0
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.5
+ /// Additional High Definition Audio Programming Steps
+ /// Step 5
+ /// Set D27:F0:40h[1] = 1b after all settings done including 19.10.5
+ ///
+ MmioOr8 (AzaliaBase + R_PCH_HDA_HDCTL, B_PCH_HDA_HDCTL_BCLD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDCTL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDCTL)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 19.4
+ /// Step 29
+ /// Set RCBA + Offset 3A6Ch[31:0] = 0x00000001, after step #26 to #28 are done
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C),
+ (UINT32) (0x00000001)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C)
+ );
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 19.4 Additional Power Management Programming
+ /// Step 30
+ /// Set RCBA + Offset 2344h[31:24] = 0xFF
+ /// Set RCBA + Offset 2344h[7:0] = 0x0C
+ ///
+ Data32And = (UINT32)~(0xFF00000F);
+ Data32Or = (UINT32) (0xFF00000C);
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + 0x2344),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2344),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ } else if (PchSeries == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.3.0 Section 31.7.2
+ /// Step 5
+ /// Set RCBA + Offset 2618h [25] = 1b.
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x2618),
+ (UINT32) (BIT25)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2618),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2618)
+ );
+ }
+/* // [ EIP357393 ]+>>>
+ ///
+ /// SPI Flash Programming Guide Section 5.5.1 Flash Configuration Lockdown
+ /// It is strongly recommended that BIOS sets the Host and GbE Flash Configuration Lock-Down (FLOCKDN)
+ /// bits (located at SPIBAR + 04h and MBAR + 04h respectively) to 1 on production platforms
+ ///
+ if (PchSeries == PchH) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN + B_PCH_SPI_PRR3PRR4_LOCKDN));
+ } else if (PchSeries == PchLp) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN));
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_SPI_HSFS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_HSFS)
+ );
+*/ // [ EIP357393 ]+<<<
+
+ ///
+ /// Set the GbE Flash Configuration Lock-Down (FLOCKDN) bit (MBAR + 04h[15]) to 1
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_ENABLE) {
+ PciD25F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 25, 0, 0);
+ ///
+ /// Enable memory space decoding in command register
+ ///
+ Data16And = 0xFFFF;
+ Data16Or = (UINT16) B_PCH_LAN_CMD_MSE;
+ MmioOr16 (PciD25F0RegBase + R_PCH_LAN_CMD, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_CMD),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+/* // [ EIP357393 ]+>>>
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MBARB) & B_PCH_LAN_MBARB_BA;
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB)
+ );
+ MmioOr16 (GbEMemBar + 0x04, BIT15);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (GbEMemBar + 0x04),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x04)
+ );
+ }
+*/ // [ EIP357393 ]+<<<
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 10.5 Additional GbE Controller Configurations for WOL Support
+ /// System BIOS requires to program the registers listed below for internal GbE.
+ /// Step 1, Set MBARA + Offset 2Ch [31] = 1b
+ /// Step 2, If WOL is enabled set MBARA + Offset 2Ch [30] = 1b
+ /// else if disabled set MBARA + Offset 2Ch [30] = 0b
+ ///
+ /// Additional Steppings:
+ /// Set MBARA + Offset 10h [31] = 1b
+ ///
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A) & B_PCH_LAN_MBARA_BA;
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A)
+ );
+ MmioOr32 (GbEMemBar + 0x2c, (BIT31));
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.WolEnableOverride) {
+ MmioOr32 (GbEMemBar + 0x2c, (BIT30));
+ } else {
+ MmioAnd32 (GbEMemBar + 0x2c, (UINT32) (~BIT30));
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (GbEMemBar + 0x2c),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x2c)
+ );
+
+ ///
+ /// Set GbEMemBar + 0x10[31] to 1b if Gbe Clkreq is in native mode (0b)
+ ///
+ if (PchSeries == PchLp) {
+ GbeRootPortNumber = PchGetGbePortNumber();
+ Data32 = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + GbeRootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ if (Data32 == 0) {
+ MmioOr32 (GbEMemBar + 0x10, BIT31);
+ } else {
+ MmioAnd32 (GbEMemBar + 0x10, (UINT32) (~BIT31));
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (GbEMemBar + 0x10),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x10)
+ );
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 11
+ /// Program D31:F2:98h [29] to 1b
+ ///
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x98), BIT29);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x98),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x98)
+ );
+ ///
+ /// Step 14
+ /// Program D31:F2:9Ch [31] to 1b
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x9C), BIT31);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x9C),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x9C)
+ );
+ ///
+ /// Do the Pcie ASPM enable prior to the end of POST
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ ///
+ /// Allcoate and Copy the entire Aspm override table pointed by DevAspmOverride to < 4G EfiReservedMemory
+ /// It's for S3 resume used.
+ ///
+ DevAspmOverrideTblSize = PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride *
+ sizeof (PCH_PCIE_DEVICE_ASPM_OVERRIDE);
+ S3DevAspmOverrideTbl = AllocateReservedCopyPool (
+ DevAspmOverrideTblSize,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride
+ );
+ ASSERT_EFI_ERROR (S3DevAspmOverrideTbl != NULL);
+
+ ///
+ /// Allcoate and Copy the entire LTR override table pointed by DevLtrOverride to < 4G EfiReservedMemory
+ /// It's used for S3 resume used.
+ ///
+ DevLtrOverrideTbl = PchPlatformPolicy->PwrOptConfig->DevLtrOverride;
+ NumOfDevltrOverride = PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride;
+ if ((DevLtrOverrideTbl != NULL) && (NumOfDevltrOverride != 0)) {
+ DevLtrOverrideTblSize = NumOfDevltrOverride * sizeof (PCH_PCIE_DEVICE_LTR_OVERRIDE);
+ S3DevLtrOverrideTbl = AllocateReservedCopyPool (
+ DevLtrOverrideTblSize,
+ DevLtrOverrideTbl
+ );
+ ASSERT_EFI_ERROR (S3DevLtrOverrideTbl != NULL);
+ }
+ ///
+ /// Check all the enabled root ports and end point devices if they support Clkreq Per Port, L1 and L1 substates
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ RPBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, GetPchPcieRpfn(RootComplexBar, PortIndex), 0);
+ if (((FuncDisableReg & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex)) == 0) && ((MmioRead16 (RPBase + R_PCH_PCIE_SLSTS) & B_PCH_PCIE_SLSTS_PDS) != 0)) {
+ RootPortAspmVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].Aspm;
+ L1SubVal = PchPcieL1SubstatesL1_1_2;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ L1SubVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].L1Substates;
+ }
+ Status = PcieCheckPmConfig (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ DevLtrOverrideTbl,
+ &(PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]),
+ &L1SubstatesSupportedPerPort,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ &AspmVal,
+ &ClkreqPerPortSupported,
+ &LtrSupported
+ );
+ if ((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) != V_PCH_PCIE_LCTL_APMC_L1) {
+ L1SupportedInAllEnabledPorts = FALSE;
+ }
+ ClkreqSupportedInAllEnabledPorts &= ClkreqPerPortSupported;
+ }
+ }
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ if ((FuncDisableReg & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex)) == 0) {
+ S3PchPwrOptPcie = AllocateReservedCopyPool (
+ sizeof (PCH_PCIE_PWR_OPT),
+ &PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]
+ );
+ ASSERT_EFI_ERROR (S3PchPwrOptPcie != NULL);
+ RootPortAspmVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].Aspm;
+ L1SubVal = PchPcieL1SubstatesL1_1_2;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ L1SubVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].L1Substates;
+ }
+ Status = PcieSetPm (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ DevLtrOverrideTbl,
+ &(PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]),
+ &L1SubstatesSupportedPerPort,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ FirstRPToSetPm,
+ L1SupportedInAllEnabledPorts,
+ ClkreqSupportedInAllEnabledPorts,
+ &LtrSupported
+ );
+ Status = SetPciePmS3Item (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ S3DevAspmOverrideTbl,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ S3DevLtrOverrideTbl,
+ S3PchPwrOptPcie,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ FirstRPToSetPm,
+ L1SupportedInAllEnabledPorts,
+ ClkreqSupportedInAllEnabledPorts
+ );
+ FirstRPToSetPm = FALSE;
+ }
+ }
+ ///
+ /// LPT-LP only: If not all devices support LTR, set RCBA + 0x3320 to 0x00010003
+ ///
+ if (!LtrSupported && (PchSeries == PchLp) ) {
+ MmioAndThenOr32 ( (RootComplexBar + 0x3320), 0, 0x00010003);
+ }
+ ///
+ /// SPI Flash Programming Guide Section 5.5.2 Vendor Component Lock
+ /// It is strongly recommended that BIOS sets the Vendor Component Lock (VCL) bits. VCL applies
+ /// the lock to both VSCC0 and VSCC1 even if VSCC0 is not used. Without the VCL bits set, it is
+ /// possible to make Host/GbE VSCC register(s) changes in that can cause undesired host and
+ /// integrated GbE Serial Flash functionality.
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_SPI_VSCC0), B_PCH_SPI_VSCC0_VCL);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_SPI_VSCC0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_VSCC0)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.4 Additional Power Management Programming
+ /// Step 3
+ /// Set GEN_PMCON_LOCK register, D31:F0:A6h = 06h, after stretch and ACPI base programming completed.
+ ///
+ MmioOr8 (
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK),
+ (UINT8) (B_PCH_LPC_GEN_PMCON_LOCK_S4_STRET_LD | B_PCH_LPC_GEN_PMCON_LOCK_ABASE_LK)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 3.6 Flash Security Recommendation
+ /// Step 1
+ /// Intel strongly recommends that BIOS enables the BIOS Lock Enable (BLE) feature of the PCH.
+ /// Left to platform code to register an callback function to handle IchnBiosWp SMI
+ ///
+ /// Step 2
+ /// Intel strongly recommends that BIOS enables SMI_LOCK (B0:D31:F0:Offset A0h [4]=1)
+ /// which prevent writes to the Global SMI Enable bit (GLB_SMI_EN PMBASE + 30h Bit
+ /// [0]). Enabling this bit will mitigate malicious software attempts to gain system management
+ /// mode privileges.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->GlobalSmi == PCH_DEVICE_ENABLE) {
+ ///
+ /// Save Global SMI Enable bit setting before BIOS enables SMI_LOCK during S3 resume
+ ///
+ Data32Or = IoRead32 ((UINTN) (PmBase + R_PCH_SMI_EN));
+ if ((Data32Or & B_PCH_SMI_EN_GBL_SMI) != 0) {
+ Data32And = 0xFFFFFFFF;
+ Data32Or &= B_PCH_SMI_EN_GBL_SMI;
+ SCRIPT_IO_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PmBase + R_PCH_SMI_EN),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ MmioOr8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), B_PCH_LPC_GEN_PMCON_SMI_LOCK);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1)
+ );
+ }
+ ///
+ /// Step 3
+ /// Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit
+ /// (RCBA+3410[0]=1 General Control and Status - BILD). Setting this bit will prevent writes
+ /// to the Backup Control Register Top Swap bit (BUC.TS RCBA + 3414 [0]) and the General
+ /// Control and Status Registers Boot BIOS Straps (RCBA + 3410h [11:10]). Enabling this bit
+ /// will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->BiosInterface == PCH_DEVICE_ENABLE) {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_GCS), (UINT32) B_PCH_RCRB_GCS_BILD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_GCS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_GCS)
+ );
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ Data32Or = MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_GCS));
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_GCS),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ }
+ ///
+ /// PCH EDS Rev 1.0, Section 14.1.35.1.2
+ /// SATA Indexed Register 1Ch Bit18, 1 = This bit allows entrance to the PCH SATA test modes when set.
+ /// This bit should only be set when following the PCH MSQT for system board testing.
+ /// It is recommended to set this bit manually.
+ ///
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.15 IntelR Stable Image Platform Program (SIPP)
+ /// For platforms supporting Intel(R) SIPP, System BIOS will need to enable the CRID feature by:
+ /// Write the value 1Dh to to the RevID field in B0:D31:F0 Offset 08h
+ ///
+
+ ///
+ /// Update CRID FVI record
+ ///
+ mPchFviElementsData[CRID_ORIGINAL].Element.Version.BuildNum = (UINT16) MmioRead8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID));
+ if (PchPlatformPolicy->DeviceEnabling->Crid == PCH_DEVICE_ENABLE) {
+ Data8 = 0x1D;
+ MmioWrite8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID), Data8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_RID),
+ 1,
+ &Data8
+ );
+ CopyMem (mPchFviElementsData[CRID_STATUS].Element.VerString, StrEnabled, sizeof (StrEnabled));
+ } else {
+ CopyMem (mPchFviElementsData[CRID_STATUS].Element.VerString, StrDisabled, sizeof (StrDisabled));
+ }
+
+ mPchFviElementsData[CRID_NEW].Element.Version.BuildNum = (UINT16) MmioRead8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID));
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 16.4 GPIO Registers Lockdown
+ /// If GPIO configurations are not used after boot, it is recommended that the GLE Lockdown Enable
+ /// and the GPIO_UNLOCK_SMI_EN bits are set by BIOS prior to end of POST.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->GpioLockDown == PCH_DEVICE_ENABLE) {
+ ///
+ /// Set GPIO Lockdown Enable bit
+ ///
+ MmioOr8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT), (UINT8) B_PCH_LPC_GPIO_LOCKDOWN_EN);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT)
+ );
+ ///
+ /// Please locate SMM ICHn SMI Dispatch Extended Protocol and register the callback function to
+ /// IchnExGpioUnlock to set GPIO_UNLOCK_SMI_EN bit in the platform code.
+ ///
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.13 BIOS guide on using RTC RAM
+ /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock and
+ /// Lower 128 Byte Lock) at RCBA + 3400h[4] and RCBA + 3400h[3]. Note once locked
+ /// bytes 0x38 - 0x3F in each of the Upper and Lower Byte blocks, respectively,
+ /// cannot be unlocked until next reset.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->RtcLock == PCH_DEVICE_ENABLE) {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF),
+ (UINT32) (B_PCH_RCRB_RTC_CONF_UCMOS_LOCK | B_PCH_RCRB_RTC_CONF_LCMOS_LOCK)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF)
+ );
+ }
+ ///
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 3.6 Flash Security Recommendation
+ /// Step 1
+ /// BIOS needs to enable the BIOS Lock Enable (BLE) feature of the PCH by setting
+ /// B0:D31:F0:DCh[1] = 1b. When this bit is set, attempts to write the BIOS Write
+ /// Enable (BIOSWE) bit in PCH will cause a SMI which will allow the BIOS to verify
+ /// that the write is from a valid source. Remember that BIOS needs to set B0:D31:F0
+ /// Offset DC [0] = 0b to enable BIOS region protection before exiting the SMI handler.
+ /// Also, TCO_EN bit needs to be set (SMI_EN Register, PMBASE + 30h[13] = 1b) to keep
+ /// BLE feature enabled after booting to the OS.
+ ///
+ /// Generate PCH IO TRAP SMI to register IchnBiosWp callback function in
+ /// PchBiosLockIoTrapCallback() to handle TCO BIOSWR SMI
+ ///
+ if ((PchPlatformPolicy->LockDownConfig->BiosLock == PCH_DEVICE_ENABLE)) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "PchBiosLockIoTrapAddress = 0x%x\n",
+ PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress)
+ );
+
+ if (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0) {
+ ///
+ /// Write PCH_BWP_SIGNATURE to IoTrap Address
+ ///
+ IoWrite32 (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress, PCH_BWP_SIGNATURE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_BIOS_CNTL),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_BIOS_CNTL)
+ );
+ }
+ }
+ ///
+ /// Lock Down TCO
+ ///
+ Data16And = 0xFFFF;
+ Data16Or = B_PCH_TCO_CNT_LOCK;
+ IoOr16(PmBase + PCH_TCO_BASE + R_PCH_TCO1_CNT, Data16Or);
+ SCRIPT_IO_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PmBase + PCH_TCO_BASE + R_PCH_TCO1_CNT),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.15.1 Additional Chipset Initialization
+ /// Step 1
+ /// Set SPIBAR + F0h [0] to 1b
+ ///
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDL), B_PCH_SPI_SRDL_SSL);
+ ///
+ /// Check to disable Smbus controller
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Smbus == PCH_DEVICE_DISABLE) {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS), (UINT32) B_PCH_RCRB_FUNC_DIS_SMBUS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS)
+ );
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ Data32Or = MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS));
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ }
+
+ UsbInitBeforeBoot (PchPlatformPolicy);
+ FoundLegacyRaid = FALSE;
+ ///
+ /// Get all PCI IO protocols
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Find the RAID BIOS by checking each PCI IO handle for RST OPROM
+ ///
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status) || (PciIo->RomImage == NULL)) {
+ ///
+ /// If this PCI device doesn't have a ROM image, skip to the next device.
+ ///
+ continue;
+ }
+
+ RomImage = PciIo->RomImage;
+
+ ///
+ /// Get pointer to PCIR structure
+ ///
+ PcirBlockPtr = (PCI_DATA_STRUCTURE *) ((UINTN) RomImage + RomImage->PcirOffset);
+
+ ///
+ /// Check if we have an RAID BIOS OPROM.
+ ///
+ if ((RomImage->Signature == 0xAA55) &&
+ (PcirBlockPtr->ClassCode[0] == 0x00) &&
+ (PcirBlockPtr->ClassCode[1] == 0x04) &&
+ (PcirBlockPtr->ClassCode[2] == 0x01)
+ ) {
+ mPchFviElementsData[RAID_VER].Element.Version.MajorVersion = (UINT8) ((PcirBlockPtr->CodeRevision & 0xFF00) >> 8);
+ mPchFviElementsData[RAID_VER].Element.Version.MinorVersion = (UINT8) (PcirBlockPtr->CodeRevision & 0x00FF);
+ mPchFviElementsData[RAID_VER].Element.Version.Revision = 0;
+ mPchFviElementsData[RAID_VER].Element.Version.BuildNum = 0;
+ FoundLegacyRaid = TRUE;
+ }
+ }
+ }
+ ///
+ /// Search EFI RST OPROM
+ ///
+ if (FoundLegacyRaid == FALSE) {
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiComponentName2ProtocolGuid,
+ (VOID **) &ComponentName2
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = ComponentName2->GetDriverName (ComponentName2, LANGUAGE_CODE_ENGLISH, &DriverName);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ if ((StrnCmp (DriverName, RstDriverName1, (sizeof (RstDriverName1) / sizeof (CHAR16)) - 1) == 0) ||
+ (StrnCmp (DriverName, RstDriverName2, (sizeof (RstDriverName2) / sizeof (CHAR16)) - 1) == 0)) {
+ Status = gBS->HandleProtocol(
+ HandleBuffer[Index],
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ (VOID**)&DriverEfiVersion);
+ mPchFviElementsData[RAID_VER].Element.Version.MajorVersion = (UINT8) ((DriverEfiVersion->FirmwareVersion & 0x00FF0000) >> 16);
+ mPchFviElementsData[RAID_VER].Element.Version.MinorVersion = (UINT8) (DriverEfiVersion->FirmwareVersion & 0x000000FF);
+ mPchFviElementsData[RAID_VER].Element.Version.Revision = 0;
+ mPchFviElementsData[RAID_VER].Element.Version.BuildNum = 0;
+ }
+ }
+ }
+ }
+
+ if (PchSeries == PchLp) {
+#ifdef SERIAL_IO_FLAG
+ ConfigureSerialIoBeforeBoot(PchPlatformPolicy, RootComplexBar);
+#endif // SERIAL_IO_FLAG
+#ifdef ADSP_FLAG
+ ConfigureAudioDspBeforeBoot (PchPlatformPolicy, RootComplexBar);
+#endif // ADSP_FLAG
+ }
+
+ //
+ // Update ASL objects
+ //
+ PchUpdateAslObjects (PchPlatformPolicy, RootComplexBar);
+
+ //
+ // Create RC FVI data hubs
+ //
+ CreateRcFviDatahub (&mPchFviVersionData);
+ }
+
+#ifdef EFI_S3_RESUME
+ if (!PchS3Support) {
+ DEBUG ((EFI_D_INFO, "Locating the S3 Support Protocol - PCH Init before Boot\n"));
+
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = PchS3Support->ReadyToLock(PchS3Support);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ }
+#endif
+
+ DEBUG ((EFI_D_INFO, "PchInitBeforeBoot() End\n"));
+
+ return;
+}
+
+// [ EIP357393 ]+>>>
+EFI_STATUS
+EFIAPI
+PchSpiLockBeforeEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Locking SPI configuration before End of Dxe
+
+Arguments:
+
+ Event A pointer to the Event that triggered the callback.
+ Context A pointer to private data registered with the callback function.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully
+
+ --*/
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINT32 RootComplexBar;
+ UINTN PciD25F0RegBase;
+ UINT32 GbEMemBar;
+ PCH_SERIES PchSeries = GetPchSeries();
+// UINT32 Data32And;
+// UINT32 Data32Or;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+// UINT8 Data8;
+ VOID *ProtocolPointer;
+
+ //
+ // Check whether this is real AMI ExtPciBusProtocol notification, or just a SignalEvent
+ //
+ Status = gBS->LocateProtocol (&gAmiExtPciBusProtocolGuid, NULL, &ProtocolPointer);
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Closed the event to avoid call twice when launch shell
+ //
+ gBS->CloseEvent (Event);
+
+
+ //
+ // Retrieve all instances of PCH Platform Policy protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return Status;
+ }
+ //
+ // Find the matching PCH Policy protocol
+ //
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return Status;
+ }
+
+ RootComplexBar = PCH_RCRB_BASE;
+
+ ///
+ /// SPI Flash Programming Guide Section 5.5.1 Flash Configuration Lockdown
+ /// It is strongly recommended that BIOS sets the Host and GbE Flash Configuration Lock-Down (FLOCKDN)
+ /// bits (located at SPIBAR + 04h and MBAR + 04h respectively) to 1 on production platforms
+ ///
+ if (PchSeries == PchH) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN + B_PCH_SPI_PRR3PRR4_LOCKDN));
+ } else if (PchSeries == PchLp) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN));
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_SPI_HSFS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_HSFS)
+ );
+ //
+ // Set the GbE Flash Configuration Lock-Down (FLOCKDN) bit (MBAR + 04h[15]) to 1
+ //
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_ENABLE) {
+ PciD25F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 25, 0, 0);
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MBARB) & B_PCH_LAN_MBARB_BA;
+ if (GbEMemBar) {
+ //
+ // Enable memory space decoding in command register
+ //
+ Data16And = 0xFFFF;
+ Data16Or = (UINT16) B_PCH_LAN_CMD_MSE;
+ MmioOr16 (PciD25F0RegBase + R_PCH_LAN_CMD, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_CMD),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB)
+ );
+ MmioOr16 (GbEMemBar + 0x04, BIT15);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (GbEMemBar + 0x04),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x04)
+ );
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+// [ EIP357393 ]+<<<