summaryrefslogtreecommitdiff
path: root/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm')
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c183
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h320
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf81
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c328
4 files changed, 912 insertions, 0 deletions
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c
new file mode 100644
index 0000000000..ed8a74b1ce
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c
@@ -0,0 +1,183 @@
+/** @file
+ SC Init Smm module for SC specific SMI handlers.
+
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "ScInitSmm.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SW_DISPATCH2_PROTOCOL *mSwDispatch;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch;
+GLOBAL_REMOVE_IF_UNREFERENCED SC_NVS_AREA *mScNvsArea;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mAcpiBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED SC_POLICY_HOB *mScPolicy;
+GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_CONFIG *mPcieRpConfig;
+
+//
+// The reserved MMIO range to be used in Sx handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mResvMmioSize;
+
+
+/**
+ PCH Sx entry SMI handler.
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+PchSxHandler (
+ IN EFI_HANDLE Handle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize PCH Sx entry SMI handler.
+
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval None
+
+**/
+VOID
+InitializeSxHandler (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext;
+ EFI_HANDLE SxDispatchHandle;
+ EFI_SLEEP_TYPE SxType;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "InitializeSxHandler() Start\n"));
+
+ //
+ // Register the callback for S3/S4/S5 entry
+ //
+ SxDispatchContext.Phase = SxEntry;
+ for (SxType = SxS3; SxType <= SxS5; SxType++) {
+ SxDispatchContext.Type = SxType;
+ Status = mSxDispatch->Register (
+ mSxDispatch,
+ PchSxHandler,
+ &SxDispatchContext,
+ &SxDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ DEBUG ((DEBUG_INFO, "InitializeSxHandler() End\n"));
+}
+
+
+/**
+ Initializes the PCH SMM handler for for PCIE hot plug support
+ <b>PchInit SMM Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The PchInitSmm module is a SMM driver that initializes the Intel Platform Controller Hub
+ SMM requirements and services. It consumes the PCH_POLICY_PROTOCOL for expected
+ configurations per policy.
+
+ - <b>Details</b>\n
+ This module provides SMI handlers to services PCIE HotPlug SMI, LinkActive SMI, and LinkEq SMI.
+ And also provides port 0x61 emulation support, GPIO Sx isolation requirement, and register BIOS WP
+ handler to process BIOSWP status.
+
+ - @pre
+ - @link _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL @endlink
+ - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+ - EFI_SMM_BASE2_PROTOCOL
+ - @link _EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL @endlink
+ - @link _EFI_SMM_SX_DISPATCH2_PROTOCOL EFI_SMM_SX_DISPATCH2_PROTOCOL @endlink
+ - @link _EFI_SMM_CPU_PROTOCOL EFI_SMM_CPU_PROTOCOL @endlink
+ - @link _PCH_SMI_DISPATCH_PROTOCOL PCH_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_PCIE_SMI_DISPATCH_PROTOCOL PCH_PCIE_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_TCO_SMI_DISPATCH_PROTOCOL PCH_TCO_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL @endlink
+ - SC_NVS_AREA_PROTOCOL
+ - @link PeiDxeSmmPchPlatformLib.h PeiDxeSmmPchPlatformLib @endlink library
+ - @link PeiDxeSmmPchPciExpressHelpersLib.h PchPciExpressHelpersLib @endlink library
+
+ - <b>References</b>\n
+ @link _PCH_POLICY PCH_POLICY_PROTOCOL @endlink.
+
+ - <b>Integration Checklists</b>\n
+ - Verify prerequisites are met. Porting Recommendations.
+ - No modification of this module should be necessary
+ - Any modification of this module should follow the PCH BIOS Specification and EDS
+
+ @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
+EFIAPI
+ScInitSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS HobPtr;
+
+ DEBUG ((DEBUG_INFO, "ScInitSmmEntryPoint()\n"));
+
+ //
+ // Locate the SMM SW dispatch protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSwDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &mSwDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSxDispatch2ProtocolGuid,
+ NULL,
+ (VOID**) &mSxDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get Sc Policy Hob
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gScPolicyHobGuid);
+ ASSERT (HobPtr.Guid != NULL);
+ mScPolicy = (SC_POLICY_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ Status = GetConfigBlock ((VOID *) mScPolicy, &gPcieRpConfigGuid, (VOID *) &mPcieRpConfig);
+ ASSERT_EFI_ERROR (Status);
+ InitializeSxHandler (ImageHandle);
+
+ Status = InitializeScPcieSmm (ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h
new file mode 100644
index 0000000000..81748ba1f0
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h
@@ -0,0 +1,320 @@
+/** @file
+ Header file for SC Init SMM Handler
+
+ Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SC_INIT_SMM_H_
+#define _SC_INIT_SMM_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/SmmCpu.h>
+#include <IndustryStandard/Pci30.h>
+#include <ScAccess.h>
+#include <Library/ScPlatformLib.h>
+#include <Library/MmPciLib.h>
+#include <Private/Library/PeiDxeSmmScPciExpressHelpersLib.h>
+#include <Private/Guid/ScPolicyHobGuid.h>
+#include <Ppi/ScPcieDeviceTable.h>
+#include <Protocol/ScPcieSmiDispatch.h>
+#include <Protocol/ScSmmIoTrapControl.h>
+#include <Private/Protocol/ScNvs.h>
+#include <Private/Protocol/PcieIoTrap.h>
+#include <Include/SiPolicyHob.h>
+#include <Library/ConfigBlockLib.h>
+
+extern EFI_SMM_SW_DISPATCH2_PROTOCOL *mSwDispatch;
+extern EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch;
+extern SC_NVS_AREA *mScNvsArea;
+extern UINT16 mAcpiBaseAddr;
+extern SC_POLICY_HOB *mScPolicy;
+extern SC_PCIE_CONFIG *mPcieRpConfig;
+extern EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+extern UINTN mResvMmioSize;
+
+#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
+} SC_PCI_ACCESS_TYPE;
+
+typedef enum {
+ Acpi,
+ Rcrb,
+ Tco
+} SC_ACCESS_TYPE;
+
+typedef struct {
+ SC_ACCESS_TYPE AccessType;
+ UINT32 Address;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+} SC_SAVE_RESTORE_REG;
+
+typedef struct {
+ SC_SAVE_RESTORE_REG* ScSaveRestoreReg;
+ UINT8 size;
+} SC_SAVE_RESTORE_REG_WRAP;
+
+struct _SC_SAVE_RESTORE_PCI;
+
+typedef struct _SC_SAVE_RESTORE_PCI{
+ SC_PCI_ACCESS_TYPE AccessType;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 BarOffset;
+ UINT16 Offset;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+ VOID (*RestoreFunction) (struct _SC_SAVE_RESTORE_PCI *ScSaveRestorePci);
+} SC_SAVE_RESTORE_PCI;
+
+typedef struct {
+ SC_SAVE_RESTORE_PCI* ScSaveRestorePci;
+ UINT8 size;
+} Sc_SAVE_RESTORE_PCI_WRAP;
+
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 PowerState;
+} DEVICE_POWER_STATE;
+
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeScPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Program Common Clock and ASPM of Downstream Devices
+
+ @param[in] PortIndex Pcie Root Port Number
+ @param[in] RpDevice Pcie Root Pci Device Number
+ @param[in] RpFunction Pcie Root Pci Function Number
+
+ @retval EFI_SUCCESS Root port complete successfully
+ @retval EFI_UNSUPPORTED PMC has invalid vendor ID
+
+**/
+EFI_STATUS
+ScPcieSmi (
+ IN UINT8 PortIndex,
+ IN UINT8 RpDevice,
+ IN UINT8 RpFunction
+ );
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+
+ @retval None
+
+**/
+VOID
+EFIAPI
+ScPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN SC_PCIE_SMI_RP_CONTEXT *RpContext
+ );
+
+/**
+ PCIE Link Equalization Request SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+
+ @retval None
+
+**/
+VOID
+EFIAPI
+ScPcieLinkEqHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN SC_PCIE_SMI_RP_CONTEXT *RpContext
+ );
+
+/**
+ The SW SMI callback to config PCIE power management settings
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] CallbackContext Pointer to the EFI_SMM_SW_REGISTER_CONTEXT
+ @param[in, out] CommBuffer Point to the CommBuffer structure
+ @param[in, out] CommBufferSize Point to the Size of CommBuffer structure
+
+**/
+VOID
+ScPciePmSwSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_REGISTER_CONTEXT *DispatchContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ );
+
+/**
+ 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
+EFIAPI
+ScInitLateSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Locate required protocol and register the 61h IO trap
+
+ @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
+EFIAPI
+InstallIoTrapPort61h (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Initialize PCH Sx entry SMI handler.
+
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval None
+
+**/
+VOID
+InitializeSxHandler (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ PCH Sx entry SMI handler.
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+ScSxHandler (
+ IN EFI_HANDLE Handle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ );
+
+/**
+ GbE Sx entry handler.
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+ScLanSxCallback (
+ VOID
+ );
+
+/**
+ This function performs GPIO Sx Isolation steps.
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+ScGpioSxIsolationCallBack (
+ VOID
+ );
+
+/**
+ Register dispatch function to handle GPIO pads Sx isolation
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+InitializeGpioSxIsolationSmm (
+ VOID
+ );
+
+/**
+ Entry point for Sc Bios Write Protect driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallScBiosWriteProtect (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf
new file mode 100644
index 0000000000..30d01b60e1
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf
@@ -0,0 +1,81 @@
+## @file
+# PchInitSmm driver.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ScInitSmm
+ FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ ENTRY_POINT = ScInitSmmEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ ScInitSmm.c
+ ScPcieSmm.c
+ ScInitSmm.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonSiPkg/BroxtonSiPrivate.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DxeServicesTableLib
+ IoLib
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ S3BootScriptLib
+ PeiDxeSmmScPciExpressHelpersLib
+ SmmServicesTableLib
+ MmPciLib
+ HobLib
+ ReportStatusCodeLib
+ DevicePathLib
+ ScPlatformLib
+ TimerLib
+ ConfigBlockLib
+
+[Guids]
+ gSiPolicyHobGuid ## UNDEFINED
+ gScDeviceTableHobGuid ## UNDEFINED
+ gScPolicyHobGuid ## UNDEFINED
+ gPcieRpConfigGuid
+
+[Protocols]
+ gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+ gScSmmIoTrapControlGuid ## CONSUMES
+ gEfiSmmCpuProtocolGuid ## CONSUMES
+ gScNvsAreaProtocolGuid ## CONSUMES
+ gScPcieSmiDispatchProtocolGuid ## CONSUMES
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid AND
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiSmmSxDispatch2ProtocolGuid AND
+ gEfiSmmCpuProtocolGuid
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c
new file mode 100644
index 0000000000..afc455b0f7
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c
@@ -0,0 +1,328 @@
+/** @file
+ PCH Pcie SMM Driver Entry.
+
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "ScInitSmm.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_DEVICE_OVERRIDE *mDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mNumOfDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPolicyRevision;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchBusNumber;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMin;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMax;
+GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_ROOT_PORT_CONFIG mPcieRootPortConfig[PCIE_MAX_ROOT_PORTS];
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mLtrNonSupportRpBitMap;
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mPciePmSwSmiExecuted = FALSE;
+
+extern EFI_GUID gScDeviceTableHobGuid;
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+
+ @retval None
+
+**/
+VOID
+EFIAPI
+ScPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN SC_PCIE_SMI_RP_CONTEXT *RpContext
+ )
+{
+ return;
+}
+
+
+/**
+ PCIE Link Equalization Request SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+
+ @retval None
+
+**/
+VOID
+EFIAPI
+ScPcieLinkEqHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN SC_PCIE_SMI_RP_CONTEXT *RpContext
+ )
+{
+ return;
+}
+
+
+/**
+ An IoTrap callback to config PCIE power management settings
+
+ @param[in] None
+
+ @retval None
+
+**/
+VOID
+ScPciePmIoTrapSmiCallback (
+ VOID
+ )
+{
+ UINT8 PortIndex;
+ UINTN RpBase;
+ UINTN RpDevice;
+ UINTN RpFunction;
+ BOOLEAN L1SubstatesSupportedPerPort;
+ UINT16 AspmVal;
+ BOOLEAN ClkreqPerPortSupported;
+ BOOLEAN ClkreqSupportedInAllEnabledPorts;
+ BOOLEAN L1SupportedInAllEnabledPorts;
+ BOOLEAN FirstRPToSetPm;
+ BOOLEAN LtrSupported;
+ BOOLEAN IsAnyRootPortEnabled;
+ UINT8 MaxPciePortNum;
+
+ AspmVal = 0;
+ L1SubstatesSupportedPerPort = FALSE;
+ ClkreqPerPortSupported = FALSE;
+ ClkreqSupportedInAllEnabledPorts = TRUE;
+ L1SupportedInAllEnabledPorts = TRUE;
+ FirstRPToSetPm = TRUE;
+ LtrSupported = TRUE;
+ IsAnyRootPortEnabled = FALSE;
+ MaxPciePortNum = GetScMaxPciePortNum ();
+
+ for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+ GetScPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+ RpBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_SC, (UINT32) RpDevice, (UINT32) RpFunction);
+
+ if ((MmioRead16 (RpBase) != 0xFFFF) &&
+ ((MmioRead16 (RpBase + R_PCH_PCIE_SLSTS) & B_PCIE_SLSTS_PDS) != 0)) {
+ PcieCheckPmConfig (
+ DEFAULT_PCI_BUS_NUMBER_SC,
+ (UINT8) RpDevice,
+ (UINT8) RpFunction,
+ mNumOfDevAspmOverride,
+ mDevAspmOverride,
+ mTempRootPortBusNumMin,
+ mTempRootPortBusNumMax,
+ &mPcieRootPortConfig[PortIndex],
+ &L1SubstatesSupportedPerPort,
+ mPolicyRevision,
+ &AspmVal,
+ &ClkreqPerPortSupported,
+ &LtrSupported
+ );
+
+ if ((AspmVal & V_PCIE_LCTL_ASPM_L1) != V_PCIE_LCTL_ASPM_L1) {
+ L1SupportedInAllEnabledPorts = FALSE;
+ }
+
+ if (ClkreqPerPortSupported == FALSE) {
+ ClkreqSupportedInAllEnabledPorts = FALSE;
+ }
+
+ if (!LtrSupported) {
+ mLtrNonSupportRpBitMap |= 1<<PortIndex;
+ }
+
+ IsAnyRootPortEnabled = TRUE;
+ }
+ }
+
+ for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+ GetScPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+ RpBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_SC, (UINT32) RpDevice, (UINT32) RpFunction);
+
+ if (MmioRead16 (RpBase) != 0xFFFF) {
+ PcieSetPm (
+ DEFAULT_PCI_BUS_NUMBER_SC,
+ (UINT8) RpDevice,
+ (UINT8) RpFunction,
+ mNumOfDevAspmOverride,
+ mDevAspmOverride,
+ mTempRootPortBusNumMin,
+ mTempRootPortBusNumMax,
+ &mPcieRootPortConfig[PortIndex],
+ &L1SubstatesSupportedPerPort,
+ mPolicyRevision,
+ FirstRPToSetPm,
+ L1SupportedInAllEnabledPorts,
+ ClkreqSupportedInAllEnabledPorts,
+ &LtrSupported,
+ TRUE
+ );
+
+ FirstRPToSetPm = FALSE;
+ }
+ }
+}
+
+
+/**
+ The SW SMI callback to config PCIE power management settings
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] CallbackContext Pointer to the EFI_SMM_SW_REGISTER_CONTEXT
+ @param[in, out] CommBuffer Point to the CommBuffer structure
+ @param[in, out] CommBufferSize Point to the Size of CommBuffer structure
+
+**/
+VOID
+ScPciePmSwSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_REGISTER_CONTEXT *DispatchContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ if (DispatchContext->SwSmiInputValue == mPcieRpConfig->AspmSwSmiNumber) {
+ if (mPciePmSwSmiExecuted == FALSE) {
+ ScPciePmIoTrapSmiCallback ();
+ mPciePmSwSmiExecuted = TRUE;
+ }
+ } else {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ }
+}
+
+
+/**
+ This function clear the Io trap executed flag before enter S3
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+ @param[in, out] CommBuffer Point to the CommBuffer structure
+ @param[in, out] CommBufferSize Point to the Size of CommBuffer structure
+
+ @retval EFI_SUCCESS PCH register saved
+
+**/
+EFI_STATUS
+EFIAPI
+ScPcieS3EntryCallBack (
+ IN EFI_HANDLE Handle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ mPciePmSwSmiExecuted = FALSE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeScPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE* Hob;
+ UINT32 DevTableSize;
+ EFI_HANDLE SwDispatchHandle;
+ EFI_SMM_SW_REGISTER_CONTEXT SwDispatchContext;
+ EFI_HANDLE SxDispatchHandle;
+ EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext;
+ UINT8 MaxPciePortNum;
+ SI_POLICY_HOB *SiPolicyHob;
+
+ DEBUG ((DEBUG_INFO, "InitializeScPcieSmm () Start\n"));
+
+ MaxPciePortNum = GetScMaxPciePortNum ();
+
+ //
+ // Get Silicon Policy data HOB
+ //
+ Hob = GetFirstGuidHob (&gSiPolicyHobGuid);
+ if (Hob == NULL) {
+ ASSERT (Hob != NULL);
+ return EFI_NOT_FOUND;
+ }
+
+ SiPolicyHob = GET_GUID_HOB_DATA (Hob);
+ mPolicyRevision = mScPolicy->TableHeader.Header.Revision;
+ mPchBusNumber = DEFAULT_PCI_BUS_NUMBER_SC;
+ mTempRootPortBusNumMin = SiPolicyHob->TempPciBusMin;
+ mTempRootPortBusNumMax = SiPolicyHob->TempPciBusMax;
+
+ ASSERT (sizeof (mPcieRootPortConfig) == sizeof (mPcieRpConfig->RootPort));
+ CopyMem (
+ mPcieRootPortConfig,
+ &(mPcieRpConfig->RootPort),
+ sizeof (mPcieRootPortConfig)
+ );
+
+ mDevAspmOverride = NULL;
+ mNumOfDevAspmOverride = 0;
+ mLtrNonSupportRpBitMap = 0;
+
+ Hob = GetFirstGuidHob (&gScDeviceTableHobGuid);
+ if (Hob != NULL) {
+ DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob);
+ ASSERT ((DevTableSize % sizeof (SC_PCIE_DEVICE_OVERRIDE)) == 0);
+ mNumOfDevAspmOverride = DevTableSize / sizeof (SC_PCIE_DEVICE_OVERRIDE);
+ DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n", mNumOfDevAspmOverride));
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ DevTableSize,
+ (VOID **) &mDevAspmOverride
+ );
+ CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob), DevTableSize);
+ }
+
+ //
+ // Register PCIe ASPM SW SMI handler
+ //
+ SwDispatchHandle = NULL;
+ SwDispatchContext.SwSmiInputValue = mPcieRpConfig->AspmSwSmiNumber;
+ Status = mSwDispatch->Register (
+ mSwDispatch,
+ (EFI_SMM_HANDLER_ENTRY_POINT2) ScPciePmSwSmiCallback,
+ &SwDispatchContext,
+ &SwDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the callback for S3 entry
+ //
+ SxDispatchContext.Type = SxS3;
+ SxDispatchContext.Phase = SxEntry;
+ Status = mSxDispatch->Register (
+ mSxDispatch,
+ ScPcieS3EntryCallBack,
+ &SxDispatchContext,
+ &SxDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "InitializeScPcieSmm () End\n"));
+
+ return EFI_SUCCESS;
+}
+