summaryrefslogtreecommitdiff
path: root/Silicon
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 12:56:23 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:15:07 +0800
commit8b318f28649a52dc7c6028bc84a7502adef9c300 (patch)
tree02332c3d231be181ae8529646cf8967eebcc0f98 /Silicon
parent3538dcf484c99fadbc3448078247b498291fd5b1 (diff)
downloadedk2-platforms-8b318f28649a52dc7c6028bc84a7502adef9c300.tar.xz
BroxtonSiPkg: Add SmmControl
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Silicon')
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf44
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c260
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h92
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf56
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c402
-rw-r--r--Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h152
6 files changed, 1006 insertions, 0 deletions
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf
new file mode 100644
index 0000000000..d882458328
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf
@@ -0,0 +1,44 @@
+## @file
+# SmmControl driver
+#
+# 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.
+#
+##
+
+[defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiSmmControl
+ FILE_GUID = FF456B9C-0DC7-4682-9E92-0DE84B6E4067
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmControlPeiDriverEntryInit
+
+[Sources]
+ SmmControlDriver.h
+ SmmControlDriver.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ IoLib
+ DebugLib
+ PcdLib
+
+[Pcd]
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES
+
+[Protocols]
+
+[Depex]
+ TRUE
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c
new file mode 100644
index 0000000000..479f9b13ed
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c
@@ -0,0 +1,260 @@
+/** @file
+ This is the driver that publishes the SMM Control Ppi.
+
+ 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.
+
+**/
+
+#include "SmmControlDriver.h"
+
+EFI_GUID mPeiSmmControlPpiGuid = PEI_SMM_CONTROL_PPI_GUID;
+
+STATIC PEI_SMM_CONTROL_PPI mSmmControlPpi = {
+ PeiActivate,
+ PeiDeactivate
+};
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &mPeiSmmControlPpiGuid,
+ &mSmmControlPpi
+};
+
+
+/**
+ This is the constructor for the SMM Control ppi
+
+ @param[in] FfsHeader FfsHeader.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Ppi
+
+**/
+EFI_STATUS
+EFIAPI
+SmmControlPeiDriverEntryInit (
+ IN EFI_PEI_FILE_HANDLE FfsHeader,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Enable the APMC SMI
+ //
+ OutputPort = AcpiBaseAddr + R_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_SMI_EN_APMC | B_SMI_EN_GBL_SMI);
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_APM_CNT;
+ OutputData = Data;
+
+ //
+ // Generate the APMC SMI
+ //
+ IoWrite8 (
+ (UINTN) OutputPort,
+ (UINT8) (OutputData)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Clear the SMI status
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT16 AcpiBaseAddr;
+
+ //
+ // Read ACPI Base Address
+ //
+ AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ //
+ // Clear the Power Button Override Status Bit, it gates EOS from being set.
+ //
+ OutputPort = AcpiBaseAddr + R_ACPI_PM1_STS;
+ OutputData = B_ACPI_PM1_STS_PRBTNOR;
+
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ //
+ // Clear the APM SMI Status Bit
+ //
+ OutputPort = AcpiBaseAddr + R_SMI_STS;
+ OutputData = B_SMI_STS_APM;
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // Set the EOS Bit
+ //
+ OutputPort = AcpiBaseAddr + R_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_SMI_EN_EOS;
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // If the EOS bit did not get set, then we've got a problem.
+ //
+ DEBUG_CODE (
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ if ((OutputData & B_SMI_EN_EOS) != B_SMI_EN_EOS) {
+ DEBUG ((EFI_D_ERROR, "Bugger, EOS did not get set!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This routine generates an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ if (Periodic) {
+ DEBUG ((EFI_D_WARN, "Invalid parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ArgumentBuffer == NULL) {
+ Data = 0xFF;
+ } else {
+ if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Data = *ArgumentBuffer;
+ }
+
+ //
+ // Clear any pending the APM SMI
+ //
+ Status = SmmClear ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return SmmTrigger (Data);
+}
+
+
+/**
+ This routine clears an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmmClear ();
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h
new file mode 100644
index 0000000000..d08b876285
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h
@@ -0,0 +1,92 @@
+/** @file
+ Header file for SMM Control Driver.
+
+ 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 _EFI_PEI_SMM_CONTROL_DRIVER_H_
+#define _EFI_PEI_SMM_CONTROL_DRIVER_H_
+
+///
+/// Driver private data
+///
+#include <PiPei.h>
+#include "Ppi/SmmControl.h"
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <ScAccess.h>
+
+///
+/// Prototypes
+///
+/**
+ This is the constructor for the SMM Control ppi
+
+ @param[in] FfsHeader FfsHeader.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Ppi
+
+**/
+EFI_STATUS
+EFIAPI
+SmmControlPeiDriverEntryInit (
+ IN EFI_PEI_FILE_HANDLE FfsHeader,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This routine generates an SMI.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance.
+ @param[in, out] ArgumentBuffer The buffer of argument.
+ @param[in, out] ArgumentBufferSize The size of the argument buffer.
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI.
+
+ @retval EFI Status Describing the result of the operation.
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ This routine clears an SMI.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance.
+ @param[in] Periodic Periodic or not.
+
+ @retval EFI Status Describing the result of the operation.
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..af5bb1b145
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,56 @@
+## @file
+# Component description file for SmmControl module
+#
+# Copyright (c) 1999 - 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 = 0x00010017
+ BASE_NAME = SmmControl
+ FILE_GUID = A0BAD9F7-AB78-491b-B583-C52B7F84B9E0
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ ENTRY_POINT = SmmControlDriverEntryInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ IoLib
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+
+[Sources]
+ SmmControlDriver.h
+ SmmControlDriver.c
+
+[Protocols]
+ gEfiSmmControl2ProtocolGuid
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
+
+[Depex]
+ TRUE
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..83576434b5
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,402 @@
+/** @file
+ This is the driver that publishes the SMM Control Protocol.
+
+ Copyright (c) 1999 - 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 "SmmControlDriver.h"
+#include <Library/ScPlatformLib.h>
+
+STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mAcpiBaseAddr;
+
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context.
+
+**/
+VOID
+EFIAPI
+SmmControlVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Trigger));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Clear));
+}
+
+
+/**
+ <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SmmControl module is a DXE RUNTIME driver that provides a standard way
+ for other drivers to trigger software SMIs.
+
+ - @pre
+ - SC Power Management I/O space base address has already been programmed.
+ If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+ is installed and there is the need to use Status code in the driver, it will
+ be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in the System Management Mode Core Interface Specification.
+
+ - @result
+ The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+ System Management Mode Core Interface Specification.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() Start\n"));
+
+ //
+ // Get the Power Management I/O space base address. We assume that
+ // this base address has already been programmed if this driver is
+ // being run.
+ //
+ mAcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+ Status = EFI_SUCCESS;
+ if (mAcpiBaseAddr != 0) {
+ //
+ // Install the instance of the protocol
+ //
+ mSmmControl.Signature = SMM_CONTROL_PRIVATE_DATA_SIGNATURE;
+ mSmmControl.Handle = ImageHandle;
+
+ mSmmControl.SmmControl.Trigger = Activate;
+ mSmmControl.SmmControl.Clear = Deactivate;
+ mSmmControl.SmmControl.MinimumTriggerPeriod = 0;
+
+ //
+ // Install our protocol interfaces on the device's handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmmControl.Handle,
+ &gEfiSmmControl2ProtocolGuid,
+ &mSmmControl.SmmControl,
+ NULL
+ );
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ return Status;
+ }
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ SmmControlVirtualAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &Event
+ );
+
+ //
+ // Disable any SC SMIs that, for whatever reason, are asserted after the boot.
+ //
+ DisablePendingSmis ();
+
+ DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() End\n"));
+
+ return Status;
+}
+
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ //
+ // Enable the APMC SMI
+ //
+ OutputPort = mAcpiBaseAddr + R_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_SMI_EN_APMC | B_SMI_EN_GBL_SMI);
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_APM_CNT;
+ OutputData = Data;
+
+ //
+ // Generate the APMC SMI
+ //
+ IoWrite8 (
+ (UINTN) OutputPort,
+ (UINT8) (OutputData)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Clear the SMI status
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Clear the Power Button Override Status Bit, it gates EOS from being set.
+ //
+ OutputPort = mAcpiBaseAddr + R_ACPI_PM1_STS;
+ OutputData = B_ACPI_PM1_STS_PRBTNOR;
+
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ //
+ // Clear the APM SMI Status Bit
+ //
+ OutputPort = mAcpiBaseAddr + R_SMI_STS;
+ OutputData = B_SMI_STS_APM;
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // Set the EOS Bit
+ //
+ OutputPort = mAcpiBaseAddr + R_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_SMI_EN_EOS;
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // There is no need to read EOS back and check if it is set.
+ // This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+ // but before the data is returned to the CPU.
+ // SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+ //
+ return Status;
+}
+
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL * This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (CommandPort == NULL) {
+ Data = 0xFF;
+ } else {
+ Data = *CommandPort;
+ }
+
+ //
+ // Clear any pending the APM SMI
+ //
+ Status = SmmClear ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return SmmTrigger (Data);
+}
+
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmmClear ();
+}
+
+
+/**
+ Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ )
+{
+ UINT32 Data;
+ UINT32 Port;
+ BOOLEAN SciEn;
+
+ //
+ // Determine whether an ACPI OS is present (via the SCI_EN bit)
+ //
+ Port = mAcpiBaseAddr + R_ACPI_PM1_CNT;
+ Data = IoRead16 ((UINTN) Port);
+ SciEn = (BOOLEAN) ((Data & B_ACPI_PM1_CNT_SCI_EN) == B_ACPI_PM1_CNT_SCI_EN);
+
+ if (!SciEn) {
+ //
+ // Clear any SMIs that double as SCIs (when SCI_EN==0)
+ //
+ Port = mAcpiBaseAddr + R_ACPI_PM1_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mAcpiBaseAddr + R_ACPI_PM1_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mAcpiBaseAddr + R_ACPI_PM1_CNT;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mAcpiBaseAddr + R_ACPI_GPE0a_STS;
+ Data = 0xFFFFFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ Port = mAcpiBaseAddr + R_ACPI_GPE0a_EN;
+ Data = 0x00000000;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+ }
+
+ //
+ // Clear and disable all SMIs that are unaffected by SCI_EN
+ //
+#if (ENBDT_PF_ENABLE == 1)
+#else
+ Port = mAcpiBaseAddr + R_ALT_GP_SMI_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mAcpiBaseAddr + R_ALT_GP_SMI_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+#endif
+
+ Port = mAcpiBaseAddr + R_SMI_STS;
+ Data = 0xFFFFFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ //
+ // (Make sure to write this register last -- EOS re-enables SMIs for the SC)
+ //
+ Port = mAcpiBaseAddr + R_SMI_EN;
+ Data = IoRead32 ((UINTN) Port);
+
+ //
+ // clear all bits except those tied to SCI_EN
+ //
+ Data &= B_SMI_EN_BIOS_RLS;
+
+ //
+ // enable SMIs and specifically enable writes to APM_CNT.
+ //
+ Data |= B_SMI_EN_GBL_SMI | B_SMI_EN_APMC;
+
+ //
+ // NOTE: Default value of EOS is set in SC, it will be automatically cleared Once the SC asserts SMI# low,
+ // we don't need to do anything to clear it
+ //
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+}
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..9cec9b2c98
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,152 @@
+/** @file
+ Header file for SMM Control Driver.
+
+ Copyright (c) 1999 - 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 _SMM_CONTROL_DRIVER_H_
+#define _SMM_CONTROL_DRIVER_H_
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/SmmControl2.h>
+#include <IndustryStandard/Pci30.h>
+#include <ScAccess.h>
+
+#define EFI_INTERNAL_POINTER 0x00000004
+#define SMM_CONTROL_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', '4', 's', 'c')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_CONTROL2_PROTOCOL SmmControl;
+} SMM_CONTROL_PRIVATE_DATA;
+
+#define SMM_CONTROL_PRIVATE_DATA_FROM_THIS(a) CR (a, SMM_CONTROL_PRIVATE_DATA, SmmControl, SMM_CONTROL_DEV_SIGNATURE)
+
+//
+// Prototypes
+//
+/**
+ <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SmmControl module is a DXE RUNTIME driver that provides a standard way
+ for other drivers to trigger software SMIs.
+
+ - @pre
+ - SC Power Management I/O space base address has already been programmed.
+ If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+ is installed and there is the need to use Status code in the driver, it will
+ be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in the System Management Mode Core Interface Specification.
+
+ - @result
+ The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+ System Management Mode Core Interface Specification.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ UINT8 Data
+ );
+
+/**
+ Clear the SMI status
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ );
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINT8 *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+/**
+ Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+#endif
+