summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/PchInit/Smm
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Chipset/LynxPoint/PchInit/Smm
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/PchInit/Smm')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c753
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs46
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h106
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl71
7 files changed, 1174 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c
new file mode 100644
index 0000000..e29c5a1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c
@@ -0,0 +1,753 @@
+/** @file
+ PCH S3 Save and Restore SMM Driver Entry
+
+@copyright
+ Copyright (c) 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 "PchLateInitSmm.h"
+
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_Common[] = {
+ {Acpi, R_PCH_ACPI_PM1_EN, 0, BIT14, 2},
+ {Rcrb, 0x3300, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x3304, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x3308, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x330C, 0, 0xFFFFFFFF, 4}
+};
+
+#ifdef TRAD_FLAG
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_PchH[] = {
+ {Acpi, R_PCH_ACPI_GPE0a_EN, 0, 0xFFFF0246, 4},
+ {Acpi, R_PCH_ACPI_GPE0b_EN, 0, 0xFF000040, 4},
+ {Tco , R_PCH_TCO2_CNT , 0, BIT5 | BIT4, 1}
+};
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_PchLp[] = {
+ {Rcrb, 0x3320, 0, 0xFFFFFFFF, 4}
+};
+#endif // ULT_FLAG
+
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_Common[] = {
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, 0, R_PCH_HDA_PCS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, PCI_BASE_ADDRESSREG_OFFSET, R_HDA_WAKEEN, 0, BIT3 | BIT2 | BIT1 | BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_USB, 0, 0, R_PCH_EHCI_PWR_CNTL_STS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_CONFIGFLAG, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 2, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 6, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 10, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 14, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 18, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 22, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 26, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 30, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 34, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 38, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_PWR_CNTL_STS + 1, 0, BIT0 | BIT7, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_USB2PR, 0, 0x7FFF, 2, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_USB3PR, 0, 0x3F, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 0, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 1, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 2, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 3, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 4, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 5, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL}
+};
+
+#ifdef TRAD_FLAG
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_PchH[] = {
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, 0, R_PCH_EHCI_PWR_CNTL_STS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_CONFIGFLAG, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 2, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 6, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 10, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 14, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 18, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 22, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 26, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 30, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 34, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 38, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 6, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 7, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL}
+};
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_PchLp[] = {
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P0DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P1DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P3DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp}
+};
+#endif // ULT_FLAG
+DEVICE_POWER_STATE DevicePowerState[] = {
+ {PCI_DEVICE_NUMBER_PCH_AZALIA, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_USB, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_XHCI, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 1, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 2, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 3, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 4, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 5, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 6, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 7, DeviceD0}
+};
+
+PCH_SAVE_RESTORE_PCI_WRAP PchSaveRestorePciRegWrap[] = {
+#ifdef TRAD_FLAG
+ {PchSaveRestorePciReg_Common, ARRAY_SIZE(PchSaveRestorePciReg_Common), PchH},
+ {PchSaveRestorePciReg_PchH, ARRAY_SIZE (PchSaveRestorePciReg_PchH), PchH}
+#endif // TRAD_FLAG
+#if (defined ULT_FLAG) && (defined TRAD_FLAG)
+ ,
+#endif // ULT_FLAG && TRAD_FLAG
+#ifdef ULT_FLAG
+ {PchSaveRestorePciReg_Common, ARRAY_SIZE(PchSaveRestorePciReg_Common), PchLp},
+ {PchSaveRestorePciReg_PchLp, ARRAY_SIZE(PchSaveRestorePciReg_PchLp), PchLp}
+#endif // ULT_FLAG
+};
+
+PCH_SAVE_RESTORE_REG_WRAP PchSaveRestoreRegWrap[] = {
+#ifdef TRAD_FLAG
+ {PchSaveRestoreReg_Common, ARRAY_SIZE(PchSaveRestoreReg_Common), PchH},
+ {PchSaveRestoreReg_PchH, ARRAY_SIZE(PchSaveRestoreReg_PchH), PchH}
+#endif // TRAD_FLAG
+#if (defined ULT_FLAG) && (defined TRAD_FLAG)
+ ,
+#endif // ULT_FLAG && TRAD_FLAG
+#ifdef ULT_FLAG
+ {PchSaveRestoreReg_Common, ARRAY_SIZE(PchSaveRestoreReg_Common), PchLp},
+ {PchSaveRestoreReg_PchLp, ARRAY_SIZE(PchSaveRestoreReg_PchLp), PchLp}
+#endif // ULT_FLAG
+};
+
+UINT32 PciMemBase = 0;
+
+/**
+
+ Find the Offset to a given Capabilities ID
+ CAPID list:
+ 0x01 = PCI Power Management Interface
+ 0x04 = Slot Identification
+ 0x05 = MSI Capability
+ 0x10 = PCI Express Capability
+
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Func - Pci Function Number
+ @param[in] CapId - CAPID to search for
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+
+**/
+UINT8
+PcieFindCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Func,
+ IN UINT8 CapId
+ )
+{
+ UINT8 CapHeader;
+
+ ///
+ /// Always start at Offset 0x34
+ ///
+ CapHeader = MmioRead8 (MmPciAddress (0, Bus, Device, Func, PCI_CAPBILITY_POINTER_OFFSET));
+ if (CapHeader == 0xFF) {
+ return 0;
+ }
+
+ while (CapHeader != 0) {
+ ///
+ /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+ ///
+ CapHeader &= ~(BIT1 | BIT0);
+ ///
+ /// Search for desired CapID
+ ///
+ if (MmioRead8 (MmPciAddress (0, Bus, Device, Func, CapHeader)) == CapId) {
+ return CapHeader;
+ }
+
+ CapHeader = MmioRead8 (MmPciAddress (0, Bus, Device, Func, CapHeader + 1));
+ }
+
+ return 0;
+}
+
+/**
+
+ Save Device Power State and restore later
+
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+
+ @retval None
+
+**/
+VOID
+SaveDevPowState (
+ IN UINT8 Device,
+ IN UINT8 Function
+ )
+{
+ UINTN index;
+
+ for (index = 0; index < ARRAY_SIZE(DevicePowerState); index++) {
+ if ((DevicePowerState[index].Device == Device) && (DevicePowerState[index].Function) == Function) {
+ DevicePowerState[index].PowerState = DeviceD3;
+ break;
+ }
+ }
+}
+
+/**
+
+ Restore Device Power State back to D3
+
+ @retval None
+
+**/
+VOID
+RestoreDevPowState (
+ VOID
+ )
+{
+ UINTN index;
+ UINTN PciBaseAddress;
+ UINT8 CapOffset;
+
+ for (index = 0; index < ARRAY_SIZE(DevicePowerState); index++) {
+ if (DevicePowerState[index].PowerState == DeviceD3) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ DevicePowerState[index].Device,
+ DevicePowerState[index].Function,
+ 0
+ );
+ CapOffset = PcieFindCapId (
+ 0,
+ DevicePowerState[index].Device,
+ DevicePowerState[index].Function,
+ EFI_PCI_CAPABILITY_ID_PCIPM
+ );
+ if (CapOffset != 0) {
+ MmioOr8 (PciBaseAddress + CapOffset + 0x4, DeviceD3);
+ }
+ }
+ }
+}
+
+/**
+ Restore PxDevSlp
+
+ @param[in] *PchSaveRestorePci - Pointer to Pch Save Restore Pci to be restored.
+
+ @retval None
+**/
+VOID
+RestorePxDevSlp(
+ IN PCH_SAVE_RESTORE_PCI *PchSaveRestorePci
+ )
+{
+ UINTN PciBaseAddress;
+ UINT32 PciBar;
+ UINTN Address;
+ UINT8 PciCmd;
+ UINT32 Data32;
+ UINT32 PortIndex;
+
+ ASSERT ((PchSaveRestorePci->AccessType == PciMmr) &&
+ (PchSaveRestorePci->Device == PCI_DEVICE_NUMBER_PCH_SATA) &&
+ ((PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P0DEVSLP) ||
+ (PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P1DEVSLP) ||
+ (PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P3DEVSLP)) &&
+ (PchSaveRestorePci->Width == 4));
+
+ PciBaseAddress = MmPciAddress (
+ 0,
+ 0,
+ PchSaveRestorePci->Device,
+ PchSaveRestorePci->Function,
+ 0
+ );
+ PortIndex = (PchSaveRestorePci->Offset - R_PCH_SATA_AHCI_P0DEVSLP)/0x80;
+ PciCmd = MmioRead8 (PciBaseAddress + PCI_COMMAND_OFFSET);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePci->BarOffset);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePci->BarOffset, PciMemBase);
+ Address = PciMemBase + PchSaveRestorePci->Offset;
+ ///
+ /// Restore DM and DITO
+ ///
+ MmioAndThenOr32 (Address, (UINT32)~PchSaveRestorePci->Mask, (PchSaveRestorePci->Data & (B_PCH_SATA_AHCI_PxDEVSLP_DM_MASK | B_PCH_SATA_AHCI_PxDEVSLP_DITO_MASK)));
+
+ ///
+ /// Makesure PxCMD.ST and PxDEVSLP.ADSE are cleared to '0' before updating PxDEVSLP.DETO and PxDEVSLP.MDAT value.
+ ///
+ Data32 = MmioRead32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)));
+ MmioAnd32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)), (UINT32)~B_PCH_SATA_AHCI_PxCMD_ST);
+ MmioAnd32 (Address, (UINT32)~B_PCH_SATA_AHCI_PxDEVSLP_ADSE);
+ MmioOr32 (Address, (PchSaveRestorePci->Data & (UINT32)~B_PCH_SATA_AHCI_PxDEVSLP_ADSE));
+ MmioOr32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)), (Data32 & B_PCH_SATA_AHCI_PxCMD_ST));
+ MmioOr32 (Address, (PchSaveRestorePci->Data & B_PCH_SATA_AHCI_PxDEVSLP_ADSE));
+
+ ///
+ /// Restore original PCI command and bar
+ ///
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, PciCmd);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePci->BarOffset, PciBar);
+}
+
+/**
+ A SMI callback to do PCH SMI register restoration
+
+ @param[in] DispatchHandle - The handle of this callback, obtained when registering
+ @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+ @retval None
+**/
+VOID
+PchIoTrapSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+{
+ UINT16 AcpiBase;
+ UINT16 TcoBase;
+ UINTN index;
+ UINTN i;
+ UINTN PciBaseAddress;
+ UINTN Address;
+ UINT8 PowerState;
+ UINT8 PciCmd;
+ UINT32 PciBar;
+ UINT32 Mask;
+ PCH_SERIES PchSeries;
+
+ AcpiBase = PchLpcPciCfg32(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ TcoBase = AcpiBase + PCH_TCO_BASE;
+ PowerState = 0x0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Restoring IO and MMIO registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestoreRegWrap); i++) {
+ if (PchSeries != PchSaveRestoreRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestoreRegWrap[i].size; index++) {
+ Mask = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Mask;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].AccessType) {
+ case Tco:
+ Address = TcoBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ IoAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ IoAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ IoAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ case Acpi:
+ Address = AcpiBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ IoAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ IoAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ IoAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ case Rcrb:
+ Address = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchMmRcrb32AndThenOr (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ PchMmRcrb16AndThenOr (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ PchMmRcrb8AndThenOr (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Restoring PCI config space and PCI bar registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestorePciRegWrap); i++) {
+ if (PchSeries != PchSaveRestorePciRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestorePciRegWrap[i].size; index++) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ 0
+ );
+ if (MmioRead32(PciBaseAddress) == 0xFFFFFFFF) {
+ continue;
+ }
+ if (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].RestoreFunction == NULL) {
+ Mask = PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Mask;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].AccessType) {
+ case PciCfg:
+ Address = PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ MmioAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data);
+ break;
+ case 2:
+ MmioAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ case 1:
+ MmioAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ }
+ break;
+ case PciMmr:
+ PciCmd = MmioRead8 (PciBaseAddress + PCI_COMMAND_OFFSET);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciMemBase);
+ Address = PciMemBase + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ MmioAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data);
+ break;
+ case 2:
+ MmioAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ case 1:
+ MmioAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ }
+ ///
+ /// Restore original PCI command and bar
+ ///
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, PciCmd);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciBar);
+ break;
+ }
+ } else {
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci [index].RestoreFunction (&(PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index]));
+ }
+ }
+ }
+}
+
+/**
+ This function save PCH register before enter S3
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+
+ @retval EFI_SUCCESS PCH register saved
+**/
+EFI_STATUS
+PchS3EntryCallBack (
+ IN EFI_HANDLE Handle,
+ IN EFI_SMM_SX_DISPATCH_CONTEXT *Context
+ )
+{
+ UINT32 AcpiBase;
+ UINT32 TcoBase;
+ UINTN PciBaseAddress;
+ UINTN index;
+ UINTN i;
+ UINT8 PowerState;
+ UINT8 CapOffset;
+ UINT32 PciBar;
+ UINT32 Mask;
+ UINT32 Address;
+ PCH_SERIES PchSeries;
+
+ AcpiBase = PchLpcPciCfg32(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ TcoBase = AcpiBase + PCH_TCO_BASE;
+ PowerState = 0x0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Saving IO and MMIO registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestoreRegWrap); i++) {
+ if (PchSeries != PchSaveRestoreRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestoreRegWrap[i].size; index++) {
+ Mask = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Mask;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].AccessType) {
+ case Tco:
+ Address = TcoBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case Acpi:
+ Address = AcpiBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case Rcrb:
+ Address = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb8 (Address)) & Mask;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Saving PCI config space and PCI bar registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestorePciRegWrap); i++) {
+ if (PchSeries != PchSaveRestorePciRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestorePciRegWrap[i].size; index++) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ 0
+ );
+ if (MmioRead32(PciBaseAddress) == 0xFFFFFFFF) {
+ continue;
+ }
+ Mask = PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Mask;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].AccessType) {
+ case PciCfg:
+ Address = (UINT32) PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case PciMmr:
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset);
+ CapOffset = PcieFindCapId (
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ EFI_PCI_CAPABILITY_ID_PCIPM
+ );
+ if (CapOffset != 0) {
+ PowerState = MmioRead8(PciBaseAddress + CapOffset + 0x4) & (BIT1 | BIT0);
+ if (PowerState == DeviceD3) {
+ ///
+ /// Bring up device to D0
+ ///
+ MmioAnd8 (PciBaseAddress + CapOffset + 0x4, (UINT8)~(BIT1 | BIT0));
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciBar);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ SaveDevPowState(PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function);
+ }
+ }
+ PciBar = PciBar & (UINT32)~(0xF);
+ if (PciBar == 0x0) {
+ continue;
+ }
+ Address = PciBar + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Restore devices to D3
+ ///
+ RestoreDevPowState();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes the PCH SMM handler for PCH save and restore
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - PCH SMM handler was installed
+**/
+EFI_STATUS
+PchLateInitSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemBase;
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *PchIoTrap;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_SX_DISPATCH_CONTEXT SxDispatchContext;
+ EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatchProtocol;
+ EFI_HANDLE SxDispatchHandle;
+ PCH_LATE_INIT_SMM_VARIABLE SaveRestoreData;
+
+ DEBUG ((EFI_D_INFO, "PchLateInitSmmEntryPoint()\n"));
+
+ ///
+ /// Locate the PCH Trap dispatch protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, &PchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ PchIoTrapContext.Type = ReadWriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = PchIoTrap->Register (
+ PchIoTrap,
+ PchIoTrapSmiCallback,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SaveRestoreData.IoTrapAddress = PchIoTrapContext.Address;
+
+ DEBUG ((EFI_D_INFO, "PchIotrapSmiAddress = 0x%x\n", PchIoTrapContext.Address));
+
+ ///
+ /// Locate the Sx Dispatch Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiSmmSxDispatchProtocolGuid,
+ NULL,
+ &SxDispatchProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Register the callback for S3 entry
+ ///
+ SxDispatchContext.Type = SxS3;
+ SxDispatchContext.Phase = SxEntry;
+ Status = SxDispatchProtocol->Register (
+ SxDispatchProtocol,
+ PchS3EntryCallBack,
+ &SxDispatchContext,
+ &SxDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MemBase = 0x0ffffffff;
+#ifndef AMI_OVERRIDE_FOR_SMM
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &MemBase,
+ ImageHandle,
+ NULL
+ );
+#else
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &MemBase,
+ ImageHandle,
+ NULL
+ );
+#endif // AMI_OVERRIDE_FOR_SMM
+ ASSERT_EFI_ERROR (Status);
+
+ PciMemBase = (UINT32) MemBase;
+
+ SaveRestoreData.PciMemBase = PciMemBase;
+
+ Status = gRT->SetVariable (
+ PCH_INIT_PEI_VARIABLE_NAME,
+ &gPchInitPeiVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (PCH_LATE_INIT_SMM_VARIABLE),
+ &SaveRestoreData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif
new file mode 100644
index 0000000..260cf93
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchLateInitSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchInit\Smm"
+ RefName = "PchLateInitSmm"
+[files]
+"PchLateInitSmm.sdl"
+"PchLateInitSmm.mak"
+"PchLateInitSmm.c"
+"PchLateInitSmm.h"
+"PchLateInitSmm.dxs"
+"PchLateInitSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs
new file mode 100644
index 0000000..32f981f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs
@@ -0,0 +1,46 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 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 a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
+#include EFI_ARCH_PROTOCOL_DEFINITION (VariableWrite)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h
new file mode 100644
index 0000000..0082af0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h
@@ -0,0 +1,106 @@
+/** @file
+ Header file for PCH SMM Handler
+
+@copyright
+ Copyright (c) 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
+**/
+
+#ifndef _PCHLATEINITSMM_H_
+#define _PCHLATEINITSMM_H_
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchInitVar.h"
+#include "pci22.h"
+#endif
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (SmmSxDispatch)
+
+#define EFI_PCI_CAPABILITY_ID_PCIPM 0x01
+
+#define DeviceD0 0x00
+#define DeviceD3 0x03
+
+#define ARRAY_SIZE(data) (sizeof (data) / sizeof (data[0]))
+
+typedef enum {
+ PciCfg,
+ PciMmr
+} PCH_PCI_ACCESS_TYPE;
+
+typedef enum {
+ Acpi,
+ Rcrb,
+ Tco
+} PCH_ACCESS_TYPE;
+
+typedef struct {
+ PCH_ACCESS_TYPE AccessType;
+ UINT32 Address;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+} PCH_SAVE_RESTORE_REG;
+
+typedef struct {
+ PCH_SAVE_RESTORE_REG* PchSaveRestoreReg;
+ UINT8 size;
+ PCH_SERIES PchSeries;
+} PCH_SAVE_RESTORE_REG_WRAP;
+
+struct _PCH_SAVE_RESTORE_PCI;
+
+typedef struct _PCH_SAVE_RESTORE_PCI{
+ PCH_PCI_ACCESS_TYPE AccessType;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 BarOffset;
+ UINT16 Offset;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+ VOID (*RestoreFunction)(struct _PCH_SAVE_RESTORE_PCI *PchSaveRestorePci);
+} PCH_SAVE_RESTORE_PCI;
+
+typedef struct {
+ PCH_SAVE_RESTORE_PCI* PchSaveRestorePci;
+ UINT8 size;
+ PCH_SERIES PchSeries;
+} PCH_SAVE_RESTORE_PCI_WRAP;
+
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 PowerState;
+} DEVICE_POWER_STATE;
+
+VOID
+RestorePxDevSlp(
+ IN PCH_SAVE_RESTORE_PCI *PchSaveRestorePci
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf
new file mode 100644
index 0000000..9f04d49
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf
@@ -0,0 +1,88 @@
+## @file
+# Component description file for the PCH late initialization SMM module.
+#
+#@copyright
+# Copyright (c) 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 a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchLateInitSmm
+FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchLateInitSmm.c
+ PchLateInitSmm.h
+ ../Common/PchInitVar.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode/Include
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[libraries.common]
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkProtocolLib
+ EfiScriptLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchLateInitSmm.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchLateInitSmmEntryPoint
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak
new file mode 100644
index 0000000..d9cf9b7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak
@@ -0,0 +1,97 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.mak 1 12/18/12 4:55a Scottyang $
+#
+# $Revision: 1 $
+#
+# $Date: 12/18/12 4:55a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.mak $
+#
+# 1 12/18/12 4:55a Scottyang
+# [TAG] EIP109697
+# [Category] Improvement
+# [Description] Update PCH RC 0.8.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# Create PchLateInitSmm Driver
+#---------------------------------------------------------------------------
+EDK : PchLateInitSmm
+PchLateInitSmm : $(BUILD_DIR)\PchLateInitSmm.mak PchLateInitSmmBin
+
+$(BUILD_DIR)\PchLateInitSmm.mak : $(PchLateInitSmm_DIR)\$(@B).cif $(PchLateInitSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchLateInitSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchLateInitSmm_INCLUDES=\
+ /I$(INTEL_PCH_DIR)\PchInit\Common\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(EDK_SOURCE)\Foundation\Efi\Include\
+
+PchLateInitSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PchLateInitSmmEntryPoint"\
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+
+PchLateInitSmm_LIB_LINKS =\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EFISCRIPTLIB)\
+ $(PchUsbCommonDxeLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchLateInitSmmBin: $(PchLateInitSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchLateInitSmm.mak all \
+ "MY_INCLUDES=$(PchLateInitSmm_INCLUDES)" \
+ "MY_DEFINES=$(PchLateInitSmm_DEFINES)" \
+ GUID=D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchLateInitSmm_DIR)\PchLateInitSmm.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl
new file mode 100644
index 0000000..efb0a48
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl
@@ -0,0 +1,71 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.sdl 1 12/18/12 4:55a Scottyang $
+#
+# $Revision: 1 $
+#
+# $Date: 12/18/12 4:55a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.sdl $
+#
+# 1 12/18/12 4:55a Scottyang
+# [TAG] EIP109697
+# [Category] Improvement
+# [Description] Update PCH RC 0.8.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+#*************************************************************************
+TOKEN
+ Name = "PchLateInitSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchLateInitSmm support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchLateInitSmm_DIR"
+End
+
+MODULE
+ File = "PchLateInitSmm.mak"
+ Help = "Includes PchLateInitSmm to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchLateInitSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************